数据庫通常被用于回答问题,“在一个表中,特定的数据有多少条?”,例如,你可能想知道你有多少宠物,或者,每个宠物拥有者有多少只宠物,或者,在普查中,你可能想知道有多少种宠物。
计算你的宠物数量与“在你的宠物表中有多少行”是同样一个问题,因为每个宠物都有一个记录。COUNT(*)可以计算行的数量,所以,统计你宠物数量可以这样:
mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
| 9 |
+----------+
早期,你查询人的名字,及此人所有宠物的数量,你会使用COUNT()来找到拥有者的宠物数量:
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Benny | 2 |
| Diane | 2 |
| Gwen | 3 |
| Harold | 2 |
+--------+----------+
前面的查询使用GROUP BY来对每个拥有者的记录进行分组。COUNT()和GROUP BY的组合使用对于各种数据分组是很有用的,以下例子显示了执行宠物普查操作的不同方式:
每个物种的动物数量:
mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird | 2 |
| cat | 2 |
| dog | 3 |
| hamster | 1 |
| snake | 1 |
+---------+----------+
每种性别的动物数量:
mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex | COUNT(*) |
+------+----------+
| NULL | 1 |
| f | 4 |
| m | 4 |
+------+----------+
(在这个输出结果中,NULL表示性别未知)
每个物种各性别对应的动物数量:
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
当你在使用时COUNT()时,你不需要检索整个表。例如,对于前面的查询,当只查询dogs和cats时,可以像这样:
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE species = 'dog' OR species = 'cat'
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
+---------+------+----------+
或者,如果你想知道,sex是已知的那些动物,每个性别所拥有的动物数量:
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE sex IS NOT NULL
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
如果你的列名被用于COUNT()来求值,一个GROUP BY谓詞应该也被用于这些列名,否则,会有如下错误:
如果ONLY_FULL_GROUP_BY模式是启用的,会发生这样的错误:
mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT owner, COUNT(*) FROM pet;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression
#1 of SELECT list contains nonaggregated column 'menagerie.pet.owner';
this is incompatible with sql_mode=only_full_group_by
如果ONLY_FULL_GROUP_BY没有启用,这个查询会把所有的行都当成一个单一的组来处理,但是,被选择出的列名的值是不确定的。服务器是自动选择了任意行的值:
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT owner, COUNT(*) FROM pet;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Harold | 8 |
+--------+----------+
1 row in set (0.00 sec)