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

Bil*_*ard 199 sql

我有以下查询:

select column_name, count(column_name)
from table
group by column_name
having count(column_name) > 1;
Run Code Online (Sandbox Code Playgroud)

会有什么区别,如果我更换了所有调用count(column_name)count(*)

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


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

SQL*_*ace 230

count(*)计数NULL而count(column)不是

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

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
Run Code Online (Sandbox Code Playgroud)

结果7 3 2

  • 值得一提的是,如果你有一个不可为空的列,比如ID,那么count(ID)将显着提高性能而不是count(*). (51认同)
  • @tsilb:@Alan发布的答案是"count(*)是通过查看有问题的表上的索引而不是实际数据行来计算的",如果为真,则会使您的评论无效.我很欣赏@Alan可能是错的,但我对您的信息来源感兴趣,以便找出哪些是正确的. (12认同)
  • @tsilb:许多现代查询优化器会优化count(*)以在有意义时使用索引. (12认同)
  • 只是好奇:如果你有_all_ NULLs的行,count(*)仍然计算它,或者只是所有列的count(列)? (8认同)
  • 这个标准是否适用于DBMS? (7认同)
  • 使用count(column_name)而不是count(\*),其中column_name不为null,应该没有任何改进.任何好处都来自使用索引扫描而不是表扫描,但优化器无论如何都可以选择对count(*)执行此操作.在Oracle中,很长一段时间都是如此. (3认同)
  • 有趣的是,这会导致count(DISTINCT列名)仅计算非空的不同值,而SELECT DISTINCT如果有一个或多个空值则返回空行. (2认同)
  • @SQLMenace如果我使用count(1)怎么办?那在哪里离开我? (2认同)

Bra*_*non 37

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

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;
Run Code Online (Sandbox Code Playgroud)

  • +1对于非明显使用DISTINCT的答案 (7认同)
  • 按列分组和计算的分组是否应该不同?否则你不会从这个查询中得到任何东西 (2认同)

Ala*_*lan 16

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

  • +1是的,对Oracle来说肯定是正确的,对于9.2以后的PostgreSQL也是如此. (5认同)

Pet*_*r C 10

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

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

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

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


Bil*_*ard 10

我们可以使用Stack Exchange Data Explorer来说明与简单查询的区别.Stack Overflow数据库中的Users表具有通常留空的列,如用户的网站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
Run Code Online (Sandbox Code Playgroud)

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