在SQL中,count(列)和count(*)之间有什么区别?

在SQL中,count(列)和count(*)之间有什么区别?

In SQL, what's the difference between count(column) and count(*)?

我有以下查询:

1
2
3
4
SELECT column_name, COUNT(column_name)
FROM TABLE
GROUP BY column_name
HAVING COUNT(column_name) > 1;

如果我将所有对count(column_name)的调用替换为count(*),会有什么区别?

这个问题的灵感来自于如何在Oracle中的表中找到重复值?

为了澄清已接受的答案(也许是我的问题),用count(*)替换count(column_name)将在结果中返回一个额外的行,该行包含null和列中null的计数值。


count(*)计数NULL,count(column)不计算

[edit]添加了此代码,以便人们可以运行它

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE #bla(id INT,id2 INT)
INSERT #bla VALUES(NULL,NULL)
INSERT #bla VALUES(1,NULL)
INSERT #bla VALUES(NULL,1)
INSERT #bla VALUES(1,NULL)
INSERT #bla VALUES(NULL,1)
INSERT #bla VALUES(1,NULL)
INSERT #bla VALUES(NULL,NULL)

SELECT COUNT(*),COUNT(id),COUNT(id2)
FROM #bla

结果
7 3 2


使用*和特定列之间的另一个细微差别是,在列情况下,您可以添加关键字DISTINCT,并将计数限制为不同的值:

1
2
3
4
SELECT column_a, COUNT(DISTINCT column_b)
FROM TABLE
GROUP BY column_a
HAVING COUNT(DISTINCT column_b) > 1;


另一个也许是微妙的区别是,在某些数据库实现中,count(*)是通过查看有问题的表上的索引而不是实际的数据行来计算的。由于没有指定特定的列,因此无需为实际的行及其值而烦恼(如果您计算了特定的列,则会如此)。允许数据库使用索引数据可能比将其计为"实际"行要快得多。


我们可以使用Stack Exchange Data Explorer来说明与简单查询的区别。 Stack Overflow数据库中的Users表具有通常留空的列,如用户的网站URL。

1
2
3
4
5
-- count(column_name) vs. count(*)
-- Illustrates the difference between counting a column
-- that can hold null values, a  'not null' column, and  count(*)

SELECT COUNT(WebsiteUrl), COUNT(Id), COUNT(*) FROM Users

如果在数据资源管理器中运行上面的查询,您将看到count(Id)count(*)的计数相同,因为Id列不允许null值。但是,WebsiteUrl计数要低得多,因为该列允许null


文档中的解释有助于解释这一点:

COUNT(*) returns the number of items in a group, including NULL values and duplicates.

COUNT(expression) evaluates expression for each row in a group and returns the number of nonnull values.

因此count(*)包含空值,另一种方法则不包含空值。


基本上,count(*)函数返回表中的所有行,而COUNT(COLUMN_NAME)则不返回;也就是说,它排除了空值,这里的每个人都在这里也回答过。
但最有趣的部分是使查询和数据库优化,除非进行多次计数或复杂查询而不是COUNT(COLUMN_NAME),否则最好使用count(*)。否则,在处理大量数据时,它会真正降低数据库性能。


count(*) - 返回表中的记录总数(包括NULL值记录)。

COUNT(Column Name) - 返回非NULL记录的总数。这意味着,它忽略了该特定列中的计数NULL值记录。


  • COUNT(*)句子表示SQL Server返回表中的所有行,包括NULL。
  • COUNT(column_name)只检索行上具有非空值的行。

请参阅下面的测试执行代码SQL Server 2008:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- Variable table
DECLARE @TABLE TABLE
(
      CustomerId INT NULL
    , Name nvarchar(50) NULL
)

-- Insert some records for tests
INSERT INTO @TABLE VALUES( NULL, 'Pedro')
INSERT INTO @TABLE VALUES( 1, 'Juan')
INSERT INTO @TABLE VALUES( 2, 'Pablo')
INSERT INTO @TABLE VALUES( 3, 'Marcelo')
INSERT INTO @TABLE VALUES( NULL, 'Leonardo')
INSERT INTO @TABLE VALUES( 4, 'Ignacio')

-- Get all the collumns by indicating *
SELECT  COUNT(*) AS 'AllRowsCount'
FROM    @TABLE

-- Get only content columns ( exluce NULLs )
SELECT  COUNT(CustomerId) AS 'OnlyNotNullCounts'
FROM    @TABLE

如前面的答案中所述,count(*)甚至计算null列,而count(Columnname)仅在列具有值时计数。

避免*(Select *count *,...)始终是最佳做法


如果您的表中有一列已修复没有区别,如果您想使用多个列而不是指定需要计算多少列......

谢谢,


最好用

1
COUNT(1) IN place OF COLUMN name OR *

要计算表中的行数,它比任何格式都要快,因为它永远不会检查列名是否存在于表中


推荐阅读