【SQL】COUNT(*) と COUNT(column) の違いとは?NULLを含む集計の注意点を解説
はじめに
SQLでデータを集計する際には、COUNT
や AVG
などの集計関数を使うことが一般的です。
ただし、NULL
が含まれる場合には、思わぬ結果になることもあるため注意が必要です。
特に COUNT(*)
と COUNT(column)
の違いや、AVG(column)
の計算方法は、
つまずきやすいポイントのひとつです。
本記事では、NULL
と集計関数の関係を整理します。
COUNT(*)
と COUNT(column)
の違い
書き方 | カウントされる条件 |
---|---|
COUNT(*) |
NULL を含むすべての行 |
COUNT(column) |
columnがNULL でない行だけ |
users
テーブルに対する実行例
id | name | |
---|---|---|
1 | 山田 太郎 | taro@example.com |
2 | 佐藤 花子 | hanako@example.com |
3 | 鈴木 次郎 | NULL |
4 | 高橋 明子 | akiko@example.com |
5 | 伊藤 三郎 | NULL |
6 | 渡辺 由美 | yumi@example.com |
このデータに対して、次のクエリを実行します。
SELECT COUNT(*) AS total, COUNT(email) AS email_count
FROM users;
クエリ結果
total | email_count |
---|---|
6 | 4 |
全体で6件、そのうち email
が NULL
でない行が4件ある、ということがわかります。
このように、COUNT(*)
は全行を数えるのに対し、
COUNT(email)
は NULL
以外の値だけを数える点に注意が必要です。
AVG(column)
もNULL
は無視される
AVG(column)
も COUNT(column)
と同様、NULL
は計算対象外になります。
SELECT AVG(score) FROM exams;
-
score
がNULL
の行は 平均値の計算に含まれません -
NULL
を除いたスコアの合計 ÷ 件数 で算出されます
exams
テーブルに対する実行例
id | student_name | score |
---|---|---|
1 | 山田 太郎 | 80 |
2 | 佐藤 花子 | 90 |
3 | 鈴木 次郎 | NULL |
4 | 高橋 明子 | 70 |
5 | 伊藤 三郎 | NULL |
6 | 渡辺 由美 | 60 |
このデータに対して、次のクエリを実行します。
SELECT AVG(score) AS average_score FROM exams;
クエリ結果
average_score |
---|
75.0 |
上の例では、NULL
でないスコアが 80, 90, 70, 60 の4件あります。
そのため AVG(score)
は (80 + 90 + 70 + 60) ÷ 4 = 75.0 になります。
NULL
を含めて集計したい場合
もしNULL
も含めて平均値を計算したい場合は、
COALESCE
やCASE WHEN
を使ってNULL
を特定の値(例:0)に置き換えます。
COALESCE
を使った場合
-- `NULL`を0として扱って平均値を計算
SELECT AVG(COALESCE(score, 0)) AS average_with_null
FROM exams;
CASE WHEN
を使った場合
-- `NULL`を0として扱って平均値を計算
SELECT AVG(
CASE
WHEN score IS NULL THEN 0
ELSE score
END
) AS average_with_null
FROM exams;
比較結果:
average_with_null |
---|
50.0 |
→ 4件のスコア(80 + 90 + 70 + 60)と、2件の NULL
(0として扱う)を合計し、6で割った結果です。
このように、NULL
を特定の値に置き換えることで、
集計結果をカスタマイズすることも可能です。
ただし、NULL
を0に置き換えるかどうかはケースバイケースなので、用途に応じて判断しましょう。
おわりに
COUNT
や AVG
は、NULL
の扱い方によって結果が変わるため、注意が必要です。
特に COUNT(*)
と COUNT(column)
の違いは、混同されやすいポイントのひとつです。
本記事が正確な集計処理の理解に役立てば幸いです。
Discussion