SQLのCOUNT(*)はNULL値をカウントする?COUNT関数の動作とNULLの扱いを解説

Oracle

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(列名)を使うことで、意図した集計結果を取得できます。

コメント

タイトルとURLをコピーしました