我想从一小部分整数(小于200)中随机选择一个值。作为
的替代方案SELECT RAND()
我正在尝试使用
CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT) / 65535
但我得到了一些奇怪的效果。
例如:
WITH Numbers (num)
AS
(
SELECT num
FROM (
VALUES (1), (2), (3), (4),
(5), (6), (7), (8),
(9), (10)
) AS Numbers (num)
),
RandomNumber (num)
AS
(
SELECT CAST(
(CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT) / 65535)
* (SELECT COUNT(*) FROM Numbers) + 1
AS INTEGER
)
)
SELECT T1.num, R1.num
FROM Numbers AS T1
INNER JOIN RandomNumber AS R1
ON T1.num = R1.num;
我希望这只返回一行,两列值相等。
但是,它返回零,一行或多行,列值仅偶尔相等。
知道这里发生了什么吗?
答案 0 :(得分:8)
试试这个:
select abs(checksum(newid()))%200
<强>更新强>
这里有一些可疑的东西:
select 'Not in the range! This is impossible!' [Message]
where cast(CAST(CAST(CRYPT_GEN_RANDOM(2) AS int) AS float) / 65535 * 10 as int)
not in (0,1,2,3,4,5,6,7,8,9)
点击F5
直到收到消息。
更新2
此查询具有相同的效果:
select 'Not in the range! This is impossible!' [Message]
where abs(checksum(newid()))%10
not in (0,1,2,3,4,5,6,7,8,9)
更新3
select N'WTF? Schrödinger''s cat!' [Message], *
from (select 0 union select 1) t(n)
join (select abs(checksum(newid()))%2 rnd) r(n) on t.n = r.n
这最后一个查询有时可能返回2行,这实际上意味着abs(checksum(newid()))%2
同时返回0和1,这是不可能的,因为它包含在“仅选择一行”语句中,因此值稍后更新在加入之后。 :|然后再次发生连接,这是令人震惊的。
更新4
Microsoft Connect上的a known bug。关于正在发生的事情,这里是an insightful article。