【问题标题】:T-SQL Query Gives Different Results when declaring integer vs calculating in-queryT-SQL 查询在声明整数和计算查询时给出不同的结果
【发布时间】:2014-11-04 08:48:03
【问题描述】:

所以我一直在尝试在查询中生成一些 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 的有用的东西。

有哪位高手能指教一下吗?

【问题讨论】:

标签: sql sql-server random


【解决方案1】:

这是 SQL Server 中 choose 函数的一个非常微妙的问题(嗯,微软可能认为它是一个特性)。该函数实际上是 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() 被多次调用。这通常不是您想要的行为。

【讨论】:

  • @AaronBertrand 。 . .谢谢你。我确实尝试使术语正确。
  • 是的,我是语义的坚持者,对不起。尤其是案例,对其工作原理的许多误解正是因为人们将其视为一种陈述。
  • 现在离题,但什么是“陈述”?我会假设一个表达式也是一个语句,虽然不是一个完整的查询?
  • @AaronBertrand 。 . .它比这更复杂。它是 Oracle 和 Postgres 脚本语言的控制流语句(同时也是一个表达式)。有很大的混淆空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 2018-08-31
  • 2014-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多