sql-server - 为每一行获取随机数

标签 sql-server tsql

我有一张表格,其中连续列出了一些名字。我想为每一行生成一个随机名称。我写了以下查询:

BEGIN transaction t1

Create table TestingName
(NameID int,
 FirstName varchar(100),
 LastName varchar(100)
)

INSERT INTO TestingName
SELECT 0,'SpongeBob','SquarePants' 
UNION 
SELECT 1, 'Bugs', 'Bunny' 
UNION 
SELECT 2, 'Homer', 'Simpson' 
UNION 
SELECT 3, 'Mickey', 'Mouse' 
UNION 
SELECT 4, 'Fred', 'Flintstone'

SELECT FirstName from TestingName
WHERE NameID = ABS(CHECKSUM(NEWID())) % 5

ROLLBACK Transaction t1

问题是此查询的“ABS(CHECKSUM(NEWID())) % 5”部分有时返回多于 1 行,有时返回 0 行。我一定是遗漏了什么,但我看不到。

如果我将查询更改为

DECLARE @n int
set @n= ABS(CHECKSUM(NEWID())) % 5

SELECT FirstName from TestingName
WHERE NameID = @n

然后一切正常,我每行得到一个随机数。

如果您采用上面的查询并将其粘贴到 SQL Management Studio 中并多次运行第一个查询,您将看到我试图描述的内容。

最终的更新查询看起来像

Update TableWithABunchOfNames
set [FName] = (SELECT FirstName from TestingName
WHERE NameID = ABS(CHECKSUM(NEWID())) % 5) 

这是行不通的,因为有时我得到不止 1 行,有时我没有任何行。

我错过了什么?

最佳答案

问题是您为每一行获得了不同的随机值。这就是问题。此查询可能正在进行全表扫描。为每一行执行 where 子句 -- 并生成一个不同的随机数。

因此,您可能会得到一个随机数序列,其中没有一个 ID 匹配。或多个匹配的序列。平均而言,您将有一场比赛,但您不想要“平均”,您想要保证。

此时您需要 rand(),它每次查询只产生一个随机数:

SELECT FirstName
from TestingName
WHERE NameID = floor(rand() * 5);

这应该为您提供一个值。

关于sql-server - 为每一行获取随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30791686/

相关文章:

sql-server - 如何避免在 Eclipselink JPA 中读取插入的 ID

c# - 内联 SQL 查询的最佳实践

sql-server - SQL Server 全文搜索使用 CONTAINS、FORMSOF、NEAR 进行多个搜索词

sql-server - 查询中包含函数吗?

c# - NULLS 应该在代码中还是在数据库中处理?的优点和缺点?

tsql - 如何使用 SQL 检查表中的日期不重叠

sql-server - SQL Server 中标量、表值和聚合函数之间的区别?

sql - 如何让一行始终显示(使用一个 View )

c# - 无法使用 smo 从 C# 执行脚本

sql-server - T-SQL CASE 检查最年轻的日期,然后对照其他值