Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

5.3.4.8 行计数

数据库经常被用来回答问题:某种类型的数据在表中出现了多少次?”例如,你可能想知道你有多少宠物,每个主人有多少宠物,或者你想对动物进行各种人口普查操作。

计算你拥有的总宠物数量与“宠物表中有多少行?””相同,因为每只宠物有一条记录。COUNT(*) 计数表中的行数,因此查询宠物数量的语句如下所示:

Press CTRL+C to copy
mysql> SELECT COUNT(*) FROM pet; +----------+ | COUNT(*) | +----------+ | 9 | +----------+

早些时候,你检索了宠物主人的人名。你可以使用 COUNT() 来查找每个主人拥有的宠物数量:

Press CTRL+C to copy
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner; +--------+----------+ | owner | COUNT(*) | +--------+----------+ | Benny | 2 | | Diane | 2 | | Gwen | 3 | | Harold | 2 | +--------+----------+

前面的查询使用 GROUP BY 将每个 owner 的所有记录分组。使用 COUNT()GROUP BY 结合可以对数据进行各种分组分析。

每种物种的动物数量:

Press CTRL+C to copy
mysql> SELECT species, COUNT(*) FROM pet GROUP BY species; +---------+----------+ | species | COUNT(*) | +---------+----------+ | bird | 2 | | cat | 2 | | dog | 3 | | hamster | 1 | | snake | 1 | +---------+----------+

每种性别的动物数量:

Press CTRL+C to copy
mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex; +------+----------+ | sex | COUNT(*) | +------+----------+ | NULL | 1 | | f | 4 | | m | 4 | +------+----------+

(在这个输出中,NULL 表示性别未知。)

每种物种和性别的动物数量:

Press CTRL+C to copy
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()。例如,前面的查询,只对狗和猫进行操作,语句如下所示:

Press CTRL+C to copy
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 | +---------+------+----------+

或者,如果你想知道性别已知的动物数量:

Press CTRL+C to copy
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 SQL 模式,将发生错误:

    Press CTRL+C to copy
    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,查询将被处理为将所有行作为一个组,但选择的列值将是非确定性的。服务器可以从任何行中选择值:

    Press CTRL+C to copy
    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)

另见 第 14.19.3 节,“MySQL Handling of GROUP BY”。见 第 14.19.1 节,“Aggregate Function Descriptions” 了解 COUNT(expr) 行为和相关优化。