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

我有以下查询:

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

如果我将count(column_name)所有调用replace为count(*)会有什么区别?

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


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

count(*)计数NULL和count(column)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

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

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

另一个可能的细微差别是,在某些数据库实现中,count(*)是通过查看所讨论的表上的索引来计算的,而不是实际的数据行。 由于没有指定特定的列,因此不需要打扰实际的行和它们的值(如果您计算特定的列)。 允许数据库使用索引数据可以比使其计算“真实”行快得多。

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

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

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

所以count(*)包含空值,另一个方法不包含。

我们可以使用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 

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

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

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

请参阅以下代码以执行testingSQL 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 

最好使用

 Count(1) in place of column name or * 

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

如果您的表格中有一列已经修复,则没有什么区别,如果您想要使用多个列,则必须指定多less列来计算……

谢谢,

正如在前面的答案中所提到的, Count(*)甚至计算NULL列,而count(Columnname)只在列有值的情况下计数。

避免*Select *count * ,…)总是最好的做法。