【问题标题】:SQL Server NULLABLE column vs SQL COUNT() functionSQL Server NULLABLE 列与 SQL COUNT() 函数
【发布时间】:2011-11-16 07:41:20
【问题描述】:

有人可以帮我理解一些事情吗?如果可以,我通常会在 SQL 语句中避免使用 (*)。好吧,今天是回报。这是一个场景:

CREATE TABLE Tbl (Id INT IDENTITY(1, 1) PRIMARY KEY, Name NVARCHAR(16))

INSERT INTO Tbl VALUES (N'John')
INSERT INTO Tbl VALUES (N'Brett')
INSERT INTO Tbl VALUES (NULL)

我可以计算NameNULL 的记录数如下:

SELECT COUNT(*) FROM Tbl WHERE Name IS NULL

在避免使用 (*) 的同时,我发现以下两个语句给了我两个不同的结果:

SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL

第一个语句正确返回 1,而第二个语句返回 0WhyHow?

【问题讨论】:

  • 你应该避免在select *中使用*,但你不应该在count(*)中避免*

标签: sql sql-server tsql count


【解决方案1】:

那是因为

COUNT(column_name) 函数返回值的个数(NULL 指定列的值将不被计算)

所以当你计算 Id 时,你会得到预期的结果,而计算 Name no,但查询提供的答案是正确的

【讨论】:

  • 天哪!我完蛋了!确实如此。 SELECT COUNT(Name) FROM Tbl 只返回没有NULL 的列数。该死的!这意味着在 COUNT 函数中使用 (*) 来评估表中的记录更安全 - 除非知道某个字段不是并且永远不会为空
  • 通常您会收到来自 SQL SERVER Null value is eliminated by an aggregate or other SET operation. 的警告,因为该问题通常会导致混淆。
【解决方案2】:

COUNT (Transact-SQL) 中描述了所有内容。

COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

ALL - 默认

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

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

【讨论】:

    【解决方案3】:

    "COUNT()" 不计算 NULL 值。所以基本上:

    SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
    

    将返回 ("ID" IS NOT NULL) AND ("Name" IS NULL) 的行数;结果是“1”

    同时:

    SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL
    

    将计算 ("Name" IS NOT NULL) AND ("Name" IS NULL);结果将始终为 0

    【讨论】:

      【解决方案4】:

      如前所述,COUNT (column_name) 不计算 NULL 值。 如果您不想使用COUNT(*),请使用COUNT(1),但实际上您不会看到性能差异。

      【讨论】:

        【解决方案5】:

        “始终避免使用 *”是人们盲目遵循的笼统陈述之一。如果您知道避免使用 * 的原因,那么您就会知道在执行 count(*) 时这些原因都不适用。

        【讨论】:

          【解决方案6】:

          COUNT(*) 中的*SELECT * FROM... 中的* 不同

          SELECT COUNT(*) FROM T; 非常具体地表示表表达式T 的基数。

          SELECT COUNT(1) FROM T; 将生成与COUNT(*) 相同的结果,但如果括号的内容不是*,则必须对其进行解析。

          SELECT COUNT(c) FROM T; 其中c 是表T 中的可空列,将计算非空值。

          附:我很乐意在适当的情况下使用 SELECT * FROM...

          附言您的“表”没有键:考虑INSERT INTO Tbl VALUES ('John', 'John', 'John', NULL, NULL, NULL); 将被允许结果将是无稽之谈。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-17
            • 2018-03-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多