来自数据库表的随机记录(T-SQL)

Jer*_*emy 80 t-sql sql-server random

是否有一种简洁的方法从sql server表中检索随机记录?

我想随机化我的单元测试数据,所以我正在寻找一种从表中选择随机id的简单方法.在英语中,select将是"从表中选择一个id,其中id是表中最低id和表中最高id之间的随机数."

我无法找到一种方法来执行它而无需运行查询,测试空值,然后重新运行,如果为null.

想法?

Skl*_*vvz 135

是否有一种简洁的方法从sql server表中检索随机记录?

SELECT TOP 1 * FROM table ORDER BY NEWID()
Run Code Online (Sandbox Code Playgroud)

说明

NEWID()为每一行生成A ,然后按表对表进行排序.返回第一个记录(即具有"最低"GUID的记录).

笔记

  1. 从第四版开始,GUID生成为伪随机数:

    版本4 UUID用于从真正随机或伪随机数生成UUID.

    算法如下:

    • 将clock_seq_hi_and_reserved的两个最高有效位(位6和7)分别设置为零和一.
    • 将time_hi_and_version字段的四个最高有效位(位12到15)设置为4.1.3节中的4位版本号.
    • 将所有其他位设置为随机(或伪随机)选择的值.

    - 通用唯一标识符(UUID)URN命名空间 - RFC 4122

  2. 替代方案SELECT TOP 1 * FROM table ORDER BY RAND()不会像人们想象的那样起作用.RAND()每个查询返回一个单值,因此所有行将共享相同的值.

  3. 虽然GUID值是伪随机的,但对于要求更高的应用程序,您需要更好的PRNG.

  4. 大约1,000,000行的典型性能不到10秒 - 当然取决于系统.请注意,不可能达到指数,因此性能相对有限.

  • @Skizz,兰德不是这样的.在SELECT之前生成SINGLE随机值.因此,如果您尝试"SELECT TOP 10 RAND()...",您将始终获得相同的值 (7认同)

Mar*_*ith 23

在较大的表格上,您也可以使用TABLESAMPLE它来避免扫描整个表格.

SELECT  TOP 1 *
FROM YourTable
TABLESAMPLE (1000 ROWS)
ORDER BY NEWID()
Run Code Online (Sandbox Code Playgroud)

ORDER BY NEWID仍然需要避免首次出现在数据页上只返回行.

需要根据表的大小和定义仔细选择要使用的数字,如果没有返回行,您可以考虑重试逻辑.这里讨论了这背后的数学以及为什么该技术不适合小型表


Skl*_*vvz 8

还可以尝试使用你的方法获得MIN(Id)和MAX(Id)之间的随机ID

SELECT TOP 1 * FROM table WHERE Id >= @yourrandomid
Run Code Online (Sandbox Code Playgroud)

它总会让你排成一排.

  • @Neil,不是真的 - 如果缺少ID,它会为你提供Id大于随机数的第一行.这里的问题是每一行出现的概率不是恒定的.但在大多数情况下,这又足够了. (5认同)
  • -1,这仅在最小值和最大值之间没有丢失ID时才有效.如果删除了一个,则随机函数生成相同的ID,您将获得零记录. (2认同)

hmf*_*ani 7

如果你想选择大数据,我知道的最好方法是:

SELECT * FROM Table1
WHERE (ABS(CAST(
    (BINARY_CHECKSUM
    (keycol1, NEWID())) as int))
    % 100) < 10
Run Code Online (Sandbox Code Playgroud)

资料来源:MSDN