我正在使用SQL Server 2012.
如果我执行以下操作以获取[1,3]范围内的随机数列表,它可以正常工作:
SELECT TOP 100
ABS(CHECKSUM(NEWID()))%3 + 1 [value_of_rand]
FROM sys.objects
Run Code Online (Sandbox Code Playgroud)
我得到了这样的好东西(1到3之间).
3
2
2
2
1
....etc.
Run Code Online (Sandbox Code Playgroud)
但是,如果我然后将相同的chained-random-value函数的输出放入CASE语句中,那么它显然不会仅生成值1,2,3.
SELECT TOP 100
CASE (ABS(CHECKSUM(NEWID()))%3 + 1)
WHEN 1
THEN 'one'
WHEN 2
THEN 'two'
WHEN 3
THEN 'three'
ELSE
'that is strange'
END [value_of_case]
FROM sys.objects
Run Code Online (Sandbox Code Playgroud)
它输出:
three
that is strange
that is strange
one
two
...etc
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
您的:
SELECT TOP 100
CASE (ABS(CHECKSUM(NEWID()))%3 + 1)
WHEN 1
THEN 'one'
WHEN 2
THEN 'two'
WHEN 3
THEN 'three'
ELSE
'that is strange'
END [value_of_case]
FROM sys.objects
Run Code Online (Sandbox Code Playgroud)
实际执行:
SELECT TOP 100
CASE
WHEN (ABS(CHECKSUM(NEWID()))%3 + 1) = 1 THEN 'one'
WHEN (ABS(CHECKSUM(NEWID()))%3 + 1) = 2 THEN 'two'
WHEN (ABS(CHECKSUM(NEWID()))%3 + 1) = 3 THEN 'three'
ELSE 'that is strange'
END [value_of_case]
FROM sys.objects;
Run Code Online (Sandbox Code Playgroud)
基本上你的表达是非确定性的,每次都被评估,所以你最终可以得到ELSE clause
.所以没有错误或捕获,只是你使用变量表达式,这是完全正常的行为.
这是同一类的 COALESCE syntactic-sugar
COALESCE表达式是CASE表达式的语法快捷方式.也就是说,代码COALESCE(expression1,... n)由查询优化器重写为以下CASE表达式:
案件
WHEN(expression1 IS NOT NULL)那么表达式1
WHEN(表达式2非空)然后表达式2
...
ELSE表达式N.
结束
这意味着将多次评估输入值(expression1,expression2,expressionN等).此外,根据SQL标准,包含子查询的值表达式被视为非确定性,子查询将被计算两次.在任何一种情况下,可以在第一次评估和随后的评估之间返回不同的结果.
编辑:
解决方案: SqlFiddle
SELECT TOP 100
CASE t.col
WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
WHEN 3 THEN 'three'
ELSE 'that is strange'
END [value_of_case]
FROM sys.objects
CROSS APPLY ( SELECT ABS(CHECKSUM(NEWID()))%3 + 1 ) AS t(col)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
265 次 |
最近记录: |