多年来我一直在说,如果您将聚合值分配给一个变量,如果没有返回行,您需要处理该变量。IE:
DECLARE @MyVar INT
SELECT @MyVar = SUM(t.MyValue) FROM dbo.MyTable t WHERE /* clause */
IF @MyVar IS NULL
SET @MyVar = 0
Run Code Online (Sandbox Code Playgroud)
然而,一位开发人员最近指出,他们不需要进行 @@ROWCOUNT 检查,因为 SUM 总是返回一个值(即使没有行)。经过进一步挖掘,我发现 SQL Server 似乎存在不一致的行为:
所以如果我运行:
DECLARE @MyTable TABLE(ID INT, MyValue INT)
/* you get a value of 0 back */
SELECT ISNULL(SUM(t.MyValue),0) FROM @MyTable t WHERE t.ID = 100
Run Code Online (Sandbox Code Playgroud)
我得到一个值为 0 的单行。
但是,如果我添加一个 GROUP BY 子句:
DECLARE @MyTable TABLE(ID INT, MyValue INT)
/* when you add on a GROUP BY, you no longer get a record back */
SELECT ISNULL(SUM(t.MyValue),0) FROM @MyTable t WHERE t.ID = 100 GROUP BY t.ID
Run Code Online (Sandbox Code Playgroud)
我没有得到任何行(这是我所期望的),我已经对 MS 文档进行了一些挖掘,但找不到关于这种行为差异的参考。谁能解释为什么会这样?这也是 SQL Server 工作方式的变化吗?
注意:我的测试是在 SQL Server 2008R2
** 编辑:回顾我过去发送的一些电子邮件并更正了我的支票,我一直在说如果值仍然为 NULL 处理它......(不处理行以及分配的 NULL)
结果是正确的,即根据标准,据我所知。
相关问题:此查询的正确结果是什么?包含解释它的段落:
以下摘自总则7.9(
GROUP BY
条款的定义)1) 如果没有
<where clause>
指定,那么让T
是前面的结果<from clause>
;否则, letT
是前面的结果<where clause>
。2) 案例:
a) 如果没有分组列,则结果
<group by clause>
是分组表T
作为其唯一的组组成。
所以,当没有GROUP BY
- 或者当我们有GROUP BY ()
- 结果应该是一个单一的组。表是否为空都没有关系。您将在结果中得到一行*。
如果表是空的(并且使用了该SUM()
函数),您将获得一个带有NULL
as 值的行- 您可以将其转换为0
using ISNULL()
。
当您有 时GROUP BY t.id
,每组将有一行。但是在您的情况下有 0 个组,因此结果中有 0 行。
* :SQL-Server 将返回 0 行用于查询GROUP BY ()
,这与标准相矛盾。
归档时间: |
|
查看次数: |
14348 次 |
最近记录: |