よくある落とし穴:集約におけるNULL
AVGがNULLを無視すること、COUNT(column)がNULLを除外すること、NULLを許容する列でグループ化したときの予想外の結果など、典型的なNULLの落とし穴を避けます。
「よくある落とし穴:集約におけるNULL」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。
集約関数はNULLを無視する
COUNT(*)以外のすべての集約関数は、NULLの入力を無視します。これは意図した動作の場合もありますが、バグになることもあります。
典型的な落とし穴:COUNT(*)とCOUNT(col)
列にNULLが含まれている場合、結果が異なります:
SELECT COUNT(*) FROM users; -- 1000
SELECT COUNT(email) FROM users; -- 950 (50 users have NULL email)バグ:AVGはNULLを0として数えない
評価 [5, 5, NULL] → AVG = 5であり、(5+5+0)/3 = 3.33ではありません。これが意図した動作かどうかを判断してください。
SELECT AVG(rating) FROM reviews; -- 5
SELECT AVG(COALESCE(rating, 0)) FROM reviews; -- 3.33空のテーブルでは集約結果がNULLになる
一致する行がない場合、SUM/AVG/MIN/MAXは0ではなくNULLを返します。COALESCEで処理してください:
SELECT COALESCE(SUM(total), 0) AS revenue
FROM orders
WHERE user_id = 999999; -- safe even when user has no ordersNULL列に対するSUM
すべての行の値がNULLの場合、SUMは0ではなくNULLを返します。これも同じ落とし穴です。
NULLのグループ化キーを使うGROUP BY
NULLは独自のグループになります:
SELECT country, COUNT(*) FROM users
GROUP BY country;
-- → ('US', 100), ('CA', 30), (NULL, 5)NULLを含む値の個数のカウント
COUNT(DISTINCT col)はNULLを無視します:
INSERT INTO t (c) VALUES (1),(2),(NULL),(NULL),(2);
SELECT COUNT(DISTINCT c) FROM t; -- 2 (NULL not counted)複数列に対するDISTINCT
NULLを含むタプルは、NULLでない列が同じでも、別のタプルとは異なる値として扱われます:
SELECT COUNT(*) FROM (
SELECT DISTINCT a, b FROM t
) sub;任意テーブルへの暗黙的なJOINに注意する
LEFT JOINによってNULLが導入され、集約結果が変わることがあります。その行もカウントするのか、除外するのかを決めてください:
SELECT u.id, COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id; -- COUNT(o.id) gives 0 for users with no orders条件付きカウントにはFILTERを使う
読みやすさの点で、FILTERはSUM内にCASEを記述する方法より優れています:
SELECT COUNT(*) FILTER (WHERE status = 'paid') AS paid_count,
COUNT(*) FILTER (WHERE status = 'refunded') AS refund_count
FROM orders;集約結果は必ずNULLを含めてテストする
新しい集約クエリを追加するときは、NULLを含むサンプルデータで実行してください。データがきれいなテストでは、このバグはほとんど現れません。
まとめ
NULLと集約の組み合わせは、SQLで最もよくあるバグです。
- 集約関数はNULLを無視します(COUNT(*)を除く)
- 空の結果は0ではなくNULLになります
- 0が必要な場合はCOALESCEで囲みます
- LEFT JOINと集約の組み合わせには十分注意します
確認問題
Reviewsの評価が [5, 5, NULL, 1] の場合、AVG(rating)は何を返しますか?
よくある質問
「よくある落とし穴:集約におけるNULL」レッスンは無料ですか?
はい。「よくある落とし穴:集約におけるNULL」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。
「よくある落とし穴:集約におけるNULL」で何を学びますか?
AVGがNULLを無視すること、COUNT(column)がNULLを除外すること、NULLを許容する列でグループ化したときの予想外の結果など、典型的なNULLの落とし穴を避けます。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「よくある落とし穴:集約におけるNULL」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Academyレッスンでコードを書いて実行できますか?
はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- COUNT、SUM、AVG、MIN、MAX
- 単一列・複数列のGROUP BY
- HAVINGとWHEREの違い
- よくある落とし穴:集約におけるNULL