COUNT(NULL)和IN子句

时间:2015-02-04 20:03:09

标签: sql-server

这更像是一个奇怪的问题。我知道这个问题似乎是一个奇怪的球,但我在检查数据时使用null,因为我并不关心那里有什么数据,只有IF数据存在。我相信以下场景只发生在SQL Server中。

当我想查看记录是否存在时,我将使用:

IF(EXISTS(SELECT null FROM Table1 WHERE Criteria IN (1, 2)))

以下代码也有效:

IF((SELECT COUNT(null) FROM Table1 WHERE Criteria = 1) = 2)

但这不起作用:

IF((SELECT COUNT(null) FROM Table1 WHERE Criteria IN (1,2)) = 2)

并收到此错误:

  

操作数数据类型NULL对于count运算符无效。

为什么第三个语句由于IN子句而有所不同?

以下是我所谈论的SQL小提琴: http://sqlfiddle.com/#!6/6d7db/8

只有在IN子句中有多个项目

时才将其缩小

2 个答案:

答案 0 :(得分:2)

COUNT(null),简称COUNT(ALL null),根本没有意义。我们来看看at the definition of COUNT(强调我的):

  

COUNT(*)返回组中的项目数。这包括NULL值和重复项。

     

COUNT(ALL表达式)计算组中每一行的表达式,并返回非空值的数量。

     

COUNT(DISTINCT表达式)计算组中每一行的表达式,并返回唯一的非空值的数量。

因此,无论您的WHERE子句匹配多少条记录,COUNT(ALL someExpressionThatYieldsNull)始终会返回0。显然,这使得它完全不适合计算行数。 COUNT(*)在这里是正确的。

我很惊讶你的第二个例子可以工作,你可能偶然发现了一个错误。在MSSQL 2012中尝试以下内容(SQLFiddle):

SELECT COUNT(NULL) FROM someTable;

产生以下错误:

  

操作数数据类型NULL对于count运算符无效。

这很有道理。

答案 1 :(得分:2)

这似乎与查询优化器有关 在前两个查询中(来自您的小提琴),count(null)似乎转换为COUNT(*),如执行计划中所示。

enter image description here
在第二行中,只有一个值的IN已优化为=,从而产生与上述完全相同的查询:

enter image description here

使用IN (1,2)查询失败。如果您使用COUNT(1),情况也是如此:它已转换为COUNT(*),其中查询只返回一行,但在第三行中保留COUNT(1)

另一个旁注:效果仅适用于真实表格。如果使用表变量,则所有三个语句都会抛出错误。

底线应该是:count(null) 错误(正如Heinzi所解释的那样),只是可能在极少数情况下通过优化器。< / p>