我有一个SQL Server表,其中有大约50,000行。我想随机选择大约5000行。我想到了一种复杂的方法,创建一个带有“随机数”列的临时表,将我的表复制到其中,循环遍历临时表并使用RAND()更新每一行,然后从该表中选择随机数列< 0.1的列。我正在寻找一种更简单的方法,如果可能的话,在一个单一的声明中。
本文建议使用NEWID()函数。这看起来很有希望,但我不知道如何可靠地选择一定百分比的行。
有人做过这个吗?什么好主意吗?
我有一个SQL Server表,其中有大约50,000行。我想随机选择大约5000行。我想到了一种复杂的方法,创建一个带有“随机数”列的临时表,将我的表复制到其中,循环遍历临时表并使用RAND()更新每一行,然后从该表中选择随机数列< 0.1的列。我正在寻找一种更简单的方法,如果可能的话,在一个单一的声明中。
本文建议使用NEWID()函数。这看起来很有希望,但我不知道如何可靠地选择一定百分比的行。
有人做过这个吗?什么好主意吗?
当前回答
select top 10 percent * from [yourtable] order by newid()
针对关于大型表的“纯粹垃圾”评论:您可以这样做以提高性能。
select * from [yourtable] where [yourPk] in
(select top 10 percent [yourPk] from [yourtable] order by newid())
这样做的成本将是值的关键扫描加上连接成本,对于一个选择百分比较小的大表来说,这应该是合理的。
其他回答
这是最初的种子思想和校验和的组合,在我看来,它可以给出适当的随机结果,而不需要NEWID()的代价:
SELECT TOP [number]
FROM table_name
ORDER BY RAND(CHECKSUM(*) * RAND())
只需按一个随机数对表进行排序,并使用TOP获得前5000行。
SELECT TOP 5000 * FROM [Table] ORDER BY newid();
更新
刚刚尝试过,一个newid()调用就足够了——不需要所有的类型转换和所有的数学运算。
select top 10 percent * from [yourtable] order by newid()
针对关于大型表的“纯粹垃圾”评论:您可以这样做以提高性能。
select * from [yourtable] where [yourPk] in
(select top 10 percent [yourPk] from [yourtable] order by newid())
这样做的成本将是值的关键扫描加上连接成本,对于一个选择百分比较小的大表来说,这应该是合理的。
newid()似乎不能在where子句中使用,所以这个解决方案需要一个内部查询:
SELECT *
FROM (
SELECT *, ABS(CHECKSUM(NEWID())) AS Rnd
FROM MyTable
) vw
WHERE Rnd % 100 < 10 --10%
select * from table
where id in (
select id from table
order by random()
limit ((select count(*) from table)*55/100))
// to select 55 percent of rows randomly