多年来我一直在说,如果您将聚合值分配给没有返回行时需要处理的变量。IE:
DECLARE @MyVar INT
SELECT @MyVar = SUM(t.MyValue) FROM dbo.MyTable t WHERE /* clause */
IF @MyVar IS NULL
SET @MyVar = 0
然而,一位开发人员最近指出,他们不需要进行@@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
我得到一个值为 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
我没有返回任何行(这是我所期望的),我已经对 MS 文档进行了一些挖掘,但找不到对这种行为差异的参考。谁能解释为什么会这样?这也是 SQL Server 工作方式的变化吗?
注意:我的测试是在 SQL Server 2008R2
** 编辑:回顾我过去发送的一些电子邮件并更正了我的支票,我一直在说如果值仍然为 NULL,请处理它...(不处理任何行并分配为 NULL)
结果是正确的,即根据标准,据我所知。
相关问题:此查询的正确结果是什么?包含解释它的段落:
所以,当没有
GROUP BY
——或者当我们有GROUP BY ()
——结果应该是一个单一的组。表是否为空并不重要。您将在结果中得到一行*。如果表为空(并且
SUM()
使用了该函数),您将获得一个带有NULL
as 值的行 - 您将其转换为0
usingISNULL()
。当你有 时
GROUP BY t.id
,每组你都会有一行。但是在您的情况下有 0 个组,因此结果中有 0 行。* :SQL-Server 将返回 0 行的查询
GROUP BY ()
,这与标准相矛盾。