我有以下疑问:

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值和列中空值的计数。


当前回答

进一步细化@SQLMeance和@Brannon给出的答案,使用OP提到但@SQLMenace的回答中没有出现的GROUP by子句

CREATE TABLE table1 ( 
id INT 
);
INSERT INTO table1 VALUES 
(1), 
(2), 
(NULL), 
(2), 
(NULL), 
(3), 
(1), 
(4), 
(NULL), 
(2);
SELECT * FROM table1;
+------+
| id   |
+------+
|    1 |
|    2 |
| NULL |
|    2 |
| NULL |
|    3 |
|    1 |
|    4 |
| NULL |
|    2 |
+------+
10 rows in set (0.00 sec)
SELECT id, COUNT(*) FROM table1 GROUP BY id;
+------+----------+
| id   | COUNT(*) |
+------+----------+
|    1 |        2 |
|    2 |        3 |
| NULL |        3 |
|    3 |        1 |
|    4 |        1 |
+------+----------+
5 rows in set (0.00 sec)

这里,COUNT(*)计数每种类型的id(包括NULL)的出现次数

SELECT id, COUNT(id) FROM table1 GROUP BY id;
+------+-----------+
| id   | COUNT(id) |
+------+-----------+
|    1 |         2 |
|    2 |         3 |
| NULL |         0 |
|    3 |         1 |
|    4 |         1 |
+------+-----------+
5 rows in set (0.00 sec)

这里,COUNT(id)计算每种类型的id的出现次数,但不计算NULL的出现次数

SELECT id, COUNT(DISTINCT id) FROM table1 GROUP BY id;
+------+--------------------+
| id   | COUNT(DISTINCT id) |
+------+--------------------+
| NULL |                  0 |
|    1 |                  1 |
|    2 |                  1 |
|    3 |                  1 |
|    4 |                  1 |
+------+--------------------+
5 rows in set (0.00 sec)

这里,COUNT(DISTINCT id)只计算每种类型id的出现次数一次(不计算重复次数),也不计算NULL的出现次数

其他回答

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

COUNT(*)返回组中的项数,包括NULL值和重复项。 COUNT(表达式)计算组中每一行的表达式,并返回非空值的数目。

所以count(*)包含空值,其他方法不包含。

正如前面的回答中提到的,Count(*)甚至对NULL列进行计数,而Count(Columnname)仅在列有值时计数。

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

进一步细化@SQLMeance和@Brannon给出的答案,使用OP提到但@SQLMenace的回答中没有出现的GROUP by子句

CREATE TABLE table1 ( 
id INT 
);
INSERT INTO table1 VALUES 
(1), 
(2), 
(NULL), 
(2), 
(NULL), 
(3), 
(1), 
(4), 
(NULL), 
(2);
SELECT * FROM table1;
+------+
| id   |
+------+
|    1 |
|    2 |
| NULL |
|    2 |
| NULL |
|    3 |
|    1 |
|    4 |
| NULL |
|    2 |
+------+
10 rows in set (0.00 sec)
SELECT id, COUNT(*) FROM table1 GROUP BY id;
+------+----------+
| id   | COUNT(*) |
+------+----------+
|    1 |        2 |
|    2 |        3 |
| NULL |        3 |
|    3 |        1 |
|    4 |        1 |
+------+----------+
5 rows in set (0.00 sec)

这里,COUNT(*)计数每种类型的id(包括NULL)的出现次数

SELECT id, COUNT(id) FROM table1 GROUP BY id;
+------+-----------+
| id   | COUNT(id) |
+------+-----------+
|    1 |         2 |
|    2 |         3 |
| NULL |         0 |
|    3 |         1 |
|    4 |         1 |
+------+-----------+
5 rows in set (0.00 sec)

这里,COUNT(id)计算每种类型的id的出现次数,但不计算NULL的出现次数

SELECT id, COUNT(DISTINCT id) FROM table1 GROUP BY id;
+------+--------------------+
| id   | COUNT(DISTINCT id) |
+------+--------------------+
| NULL |                  0 |
|    1 |                  1 |
|    2 |                  1 |
|    3 |                  1 |
|    4 |                  1 |
+------+--------------------+
5 rows in set (0.00 sec)

这里,COUNT(DISTINCT id)只计算每种类型id的出现次数一次(不计算重复次数),也不计算NULL的出现次数

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

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

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

结果 7 3 2