【发布时间】:2011-03-03 10:10:29
【问题描述】:
以下(简化的)代码片段的目的是返回一个随机行。 不幸的是,当我们在查询分析器中运行这个片段时,它会返回零到三个结果。
由于我们的输入表正好由具有唯一 ID 的 5 行组成,并且当我们在这个 ID 等于一个随机数的表上执行选择时,我们很难过会有不止一行回来。
注意:除此之外,我们已经尝试将校验和结果转换为整数,但无济于事。
DECLARE @Table TABLE (
ID INTEGER IDENTITY (1, 1)
, FK1 INTEGER
)
INSERT INTO @Table
SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
SELECT *
FROM @Table
WHERE ID = ABS(CHECKSUM(NEWID())) % 5 + 1
编辑
我们的使用场景如下(请不要评论这样做是否正确。这是权力决定的)
最终,我们必须通过从表本身中随机选择现有权重来创建具有现实值的结果,其中生产者和权重的组合被混淆。
然后查询会变成这样(也是RAND不能使用的原因)
SELECT t.ID
, FK1 = (SELECT FK1 FROM @Table WHERE ID=ABS(CHECKSUM(NEWID())) % 5 + 1)
FROM @Table t
因为内部选择可能返回零结果,所以它会返回一个 NULL 值,这又是不可接受的。正是调查了为什么内部选择在零和 x 结果之间返回,这个问题引起了(这甚至是英语吗?)。
回答
让我大开眼界的是ABS(CHECKSUM(NEWID())) % 5 + 1) 被重新评估每一行的简单观察。我的印象是ABS(CHECKSUM(NEWID())) % 5 + 1) 会被评估一次,然后匹配。
感谢大家的回答,慢慢但肯定会引导我更好地理解。
【问题讨论】:
-
在多个输出行中是否有来自同一行的 FK1 值?
-
我不认为这是个问题。
-
顺便说一句 - 我不相信“sproused”是一个词。 'Sprouse' 被用作姓氏,这让我相信它可能是中古英语或更早的一个词,但它的含义显然已经丢失。
-
@Bob Jarvis,请随时编辑和增强问题。我知道我的意思(显然),但我不知道如何翻译。
标签: sql sql-server sql-server-2005 random