SQLでデータ件数を取得するときによく利用されるCOUNT関数ですが、NULL値が存在する場合にどのような結果になるのかは、データベース初心者が混乱しやすいポイントです。特にCOUNT(*)とCOUNT(列名)ではNULLの扱いが異なるため、目的に応じた使い分けが必要になります。
この記事では、COUNT(*)がNULL値をどのように扱うのか、COUNT(列名)との違いや具体的な例を使って分かりやすく解説します。
COUNT(*)はNULL値を含めてすべての行をカウントする
SQLのCOUNT(*)は、対象テーブルの行数を数えるために使用されます。カウント対象は列の値ではなく「存在する行」そのものです。
そのため、対象行の中にNULL値が含まれていてもCOUNT(*)では除外されません。
例えば、以下のようなusersテーブルがあるとします。
| id | name | email |
|—|—|—|
| 1 | 山田 | test@example.com |
| 2 | 佐藤 | NULL |
| 3 | 鈴木 | sample@example.com |
このテーブルに対して以下のSQLを実行します。
SELECT COUNT(*) FROM users;
結果は「3」になります。email列の2行目がNULLであっても、行自体は存在しているためカウントされます。
COUNT(列名)ではNULL値はカウントされない
一方で、COUNTの引数に特定の列名を指定した場合、その列の値がNULLの行はカウント対象外になります。
例えば、先ほどのusersテーブルで以下のSQLを実行します。
SELECT COUNT(email) FROM users;
この場合、結果は「2」になります。email列に値が入っている行だけを数えるため、NULLの1行は除外されます。
つまり、COUNT(列名)は「その列に値が存在するデータの数」を取得する場合に利用します。
COUNT(*)とCOUNT(列名)の使い分け
COUNT(*)とCOUNT(列名)は似ていますが、目的が異なります。
テーブルに存在する全データ件数を知りたい場合はCOUNT(*)を使用します。例えば、会員数、注文数、ログ件数などを取得するときに適しています。
一方で、特定の項目が入力されている件数を調べたい場合はCOUNT(列名)を使用します。
例えば、メールアドレス登録済みのユーザー数を確認したい場合は以下のようになります。
SELECT COUNT(email) FROM users;
この場合、メールアドレスが未登録(NULL)のユーザーは除外されるため、実際にメールアドレスを持つユーザー数を取得できます。
COUNT(*)がNULLを評価しているように見える理由
COUNT(*)ではNULLをカウントしているように見えることがありますが、実際にはNULLという値を数えているわけではありません。
COUNT(*)は列の内容を確認せず、単純に「存在するレコード数」を数えています。そのため、NULLがあるかどうかは関係ありません。
例えば、以下のようなデータでもCOUNT(*)の結果は同じになります。
| id | value |
|—|—|
| 1 | 100 |
| 2 | NULL |
| 3 | NULL |
SELECT COUNT(*) FROM table_name;
この結果は「3」です。NULLが2つあるから3件になるのではなく、3行存在するため3件になります。
SQLでNULLを扱うときに注意すべきポイント
SQLではNULLは「空文字」や「0」とは異なる特殊な値として扱われます。そのため、COUNT関数以外でもNULLの扱いには注意が必要です。
例えば、WHERE句でNULLを検索するときは以下のように記述します。
SELECT * FROM users WHERE email IS NULL;
「email = NULL」のような比較は正しく動作しません。NULLは通常の値との比較では判定できないため、IS NULLやIS NOT NULLを利用します。
COUNT関数についても同様に、NULLを含むデータを扱う場合は、COUNT(*)なのかCOUNT(列名)なのかを意識することが重要です。
まとめ
SQLのCOUNT(*)は、対象列のNULL値を評価して数えているわけではなく、テーブル内に存在するすべての行数をカウントしています。そのため、NULLを含む行も結果に含まれます。
一方、COUNT(列名)では指定した列の値がNULLの場合、その行はカウントされません。
データ全体の件数を取得したい場合はCOUNT(*)、特定の列に値が入っている件数を知りたい場合はCOUNT(列名)を使うことで、意図した集計結果を取得できます。


コメント