在SQL中,count(column)和count(*)有什么区别?


205

我有以下查询:

select column_name, count(column_name)
from table
group by column_name
having count(column_name) > 1;

会有什么区别,如果我更换,所有呼叫count(column_name)count(*)

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


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

Answers:


235

count(*)计算NULL而count(column)不会

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

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


8
只是好奇:如果您有一个全为 NULL 的行,count(*)仍会计数,还是所有列的count(column)个?
Joel Coehoorn

7
DBMS是否采用此标准?
Eclipse的

51
值得一提的是,如果您有一个不可为空的列,例如ID,那么count(ID)将大大提高count(*)的性能。
tsilb

12
@tsilb:@Alan发布的答案指出“ count(*)是通过查看相关表上的索引而不是实际数据行来计算的”,如果为true,则会使您的注释无效。感谢@Alan可能是错的,但我对您的信息来源感兴趣,以便找出正确的信息。
托尼2010年

12
@tsilb:许多现代查询优化器会在必要时优化count(*)以使用索引。
Shannon Severance 2010年

37

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

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;

1
列和被计数的分组应该不同吗?否则,您不会从此查询中获得任何信息
steevc

是的,很抱歉..我没有注意到它们与示例中的列相同。我将更新帖子。
布兰农

16

另一个甚至是微妙的区别是,在某些数据库实现中,count(*)是通过查看相关表的索引而不是实际数据行来计算的。由于未指定特定的列,因此无需理会实际的行及其值(就像您对特定的列进行计数一样)。允许数据库使用索引数据可能比使它计数“真实”行快得多。


5
+1是,对于Oracle和9.2以后的PostgreSQL确实如此。
David Aldridge

@DavidAldridge能否提供提及文档的指针(特别是对于Postgresql)?谢谢。
Bhushan

@Bhushan,这就是您要去的地方wiki.postgresql.org/wiki/Index-only_scans
David Aldridge

10

docs中的解释有助于对此进行解释:

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

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

因此count(*)包含null,而其他方法则不包含null。


对于SQL newbs:您要指向哪个帮助文件?
比尔蜥蜴

10

我们可以使用Stack Exchange Data Explorer通过简单的查询来说明差异。Stack Overflow数据库中的“用户”表中的列通常为空白,例如用户的网站URL。

-- 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

如果您在Data Explorer中运行上面的查询,您将看到的计数是相同的,count(Id)并且count(*)因为该Id列不允许使用null值。WebsiteUrl但是,该计数要低得多,因为该列允许null


2

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


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

请查看以下代码以执行SQL Server 2008的测试:

-- 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

1

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

COUNT(Column Name) –返回非NULL记录的总数。这意味着,它将忽略对特定列中的NULL值记录进行计数。


0

最好用

Count(1) in place of column name or * 

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


4
至少对于Oracle以及我对其他RDBMS来说也是不正确的。内部将count(1)转换为count(*)。特别是,count(*)的性能不受行大小的不利影响,这是一种常见的误解。
David Aldridge

对于SQL Server来说确实如此。就像@Ali Adravi所说COUNT(*)的相比,COUNT(columnName)不会去检查列的值,因为它只是枚举行。但是COUNT(columnName),即使在列count上应用,速度也较慢id!当然,至少在SQL Server中。
ABS

0

如果表中的一列是固定的,如果要使用多于一列,而不必指定需要计数的列,则没有区别……

谢谢,


0

如前面的答案中所述,Count(*)即使NULL列也count(Columnname)计数,而仅在列具有值时才计数。

它总是以避免最佳实践*Select *count *,...)


这不是在所有避免最佳实践COUNT(*)
大卫·费伯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.