【发布时间】:2014-02-20 20:14:38
【问题描述】:
我需要将一些测试数据加载到我的帐户表的渠道字段中。 Channel 可以是 10 个不同的值之一,所以我想我会使用 CASE 表达式和 ABS(CHECKSUM(NewId())) % 10 随机分配一个值,如下所示:
SELECT
id,
name,
Channel =
CASE ABS(CHECKSUM(NewId())) % 10
WHEN 0 THEN 'Baby Only'
WHEN 1 THEN 'Club'
WHEN 2 THEN 'Drug'
WHEN 3 THEN 'Food'
WHEN 4 THEN 'Internet'
WHEN 5 THEN 'Liquidators'
WHEN 6 THEN 'Mass'
WHEN 7 THEN 'Military'
WHEN 8 THEN 'Other'
WHEN 9 THEN 'Speciality'
ELSE '*NONE*' -- How is this ever getting reached?
END
FROM
retailshelf_nil...account A
由于我使用的是模 10,我认为唯一可能的值应该是 0-9。但是当我运行上面的代码时,我发现ELSE 子句确实已经到达,并且我的数据在某些记录上显示为“NONE”,如下所示:
id name Channel
001L000000KpgFqIAJ Acct1 *NONE*
001L000000KpgFrIAJ Acct2 Mass
001L000000KpgFsIAJ Acct3 Club
001L000000KpgFtIAJ Acct4 *NONE*
001L000000KpgFuIAJ Acct5 Baby Only
001L000000KpgFvIAJ Acct6 *NONE*
001L000000KpgFwIAJ Acct7 Mass
谁能解释一下我犯了什么逻辑错误导致 ELSE 子句可以到达?
当我运行一个简单的测试来生成随机数时:
SELECT
RadomNum = ABS(CHECKSUM(NewId())) % 10
FROM
retailshelf_nil...account A
ORDER BY
1
生成的所有数字都如预期的那样从 0 到 9,那么第一个 SQL 有什么不同?
是否有解决方法来确保永远不会到达ELSE?
【问题讨论】:
-
当
ABS(CHECKSUM(NewId()))返回 NULL 时,将执行 ELSE。这将在 NewId() 返回 NULL 时发生。 -
@DwB,感谢您的回复,但为什么 NEWID() 会返回 NULL?
-
如果你只是在寻找一个随机值并且你得到的值不是其他的,为什么不直接将其他值汇总到你的其他值之一中,否则也会是“专业”作为 9,这肯定会搞砸偏差,但这可能无关紧要。
-
There is an answer that explains exactly why this happens -
NEWID()在 CASE 表达式的每个分支中重新计算,您的计算可能恰好是1 0 0 0 0 0 0 0 0 0,例如,对于某些行,这会导致其他的。 -
@PaulStock 我的思路是错误的。 newid() 永远不应返回 null。
标签: sql sql-server-2008 tsql