在声明整数与计算查询时,T-SQL查询给出不同的结果

时间:2014-09-10 15:55:16

标签: sql sql-server random

所以我一直在查询中尝试一些SQL随机数生成,我注意到了一些奇怪的事情。

假设我运行以下查询:

declare @Random int = CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) + 1;

select CHOOSE(@Random,'One','Two','Three','Four','Five')

SQL随机数gen有点笨重,但这里的基本思路很简单 - 选择1到5之间的随机数,然后将该数字作为文本显示在选择窗口中。这可以按预期工作。

但是,如果我接受SAME查询,但是将随机数公式粘贴到方法中而不是将其声明为整数,那么它就在一行上:

select CHOOSE(CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) +
    1,'One','Two','Three','Four','Five')

当我运行查询时,我仍然得到值1到5,但有时我也得到NULL。 NULL经常出现,大约五次出现。如果我将两个查询都放入ssms并将它们彼此相邻运行几次,我经常会看到第二个查询的空值,但第一个查询永远不会为NULL。

那为什么呢?这些计算不完全相同吗?我不知道为什么这两个查询会产生不同的结果,但我觉得我可以通过查找来了解有关T-SQL的有用信息。

有专家想开导我吗?

1 个答案:

答案 0 :(得分:9)

这是SQL Server中choose函数的一个非常微妙的问题(好吧,Microsoft可能认为它是一个特性)。该函数实际上是case表达式的简写。所以,你的表达:

select CHOOSE(CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) +
1,'One','Two','Three','Four','Five')

被翻译成:

select (case when CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) + 1 = 1 then 'One'
             when CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) + 1 = 2 then 'Two'
             when CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) + 1 = 3 then 'Three'
             when CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) + 1 = 4 then 'Four'
             when CAST(RAND(CHECKSUM(NEWID())) * 5 as INT) + 1 = 5 then 'Five'
        end)

这意味着多次调用newid()。这通常不是您想要的行为。