MySQL 8.0 リファレンスマニュアル


3.3.4.8 行のカウント

データベースは、テーブルの中に、特定のタイプのデータがどの程度の頻度で現れるかという質問に答えるために使用されることがよくあります。 たとえば、何匹ペットを飼っているのか、それぞれの所有者が何匹のペットを所有しているかを調べたり、または動物に対してさまざまな個体数調査を実施したりすることがあるでしょう。

ペットの総数をカウントすることは、pet テーブルには何行あるかという質問と同等です。このテーブルにはペットごとに 1 つのレコードが存在するからです。 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 を使用して各 owner のすべてのレコードをグループ化しています。 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() を使用するときにテーブル全体を取り出す必要はありません。 たとえば、前のクエリーを犬と猫だけに対して実行する場合は、次のようになります。

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 |
+---------+------+----------+

または、性別のわかっているペットについてのみ性別ごとのペット数を調べるには:

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 モードが有効である場合は、エラーが発生します。

    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)

セクション12.20.3「MySQL での GROUP BY の処理」も参照してください。 COUNT(expr) の動作および関連する最適化の詳細は、セクション12.20.1「集計関数の説明」 を参照してください。


関連キーワード:  COUNT, species, ペット, sex, カウント, テーブル, FROM, カラム, owner, cat