CodeGym /コース /SQL SELF /よくある NULL のミス

よくある NULL のミス

SQL SELF
レベル 10 , レッスン 4
使用可能

このレクチャーでは、ちょっと謎めいた存在 NULL についてもっと深く知っていこう。もちろん、みんなが自分でミスるのはこれからだけど…知っておけば安心だよね。じゃあ、 NULL に関する典型的なミスをいくつか見てみよう。

ミス1: 普通の = オペレーターで NULL をチェックしちゃう

SQL初心者が一番やりがちなミスは、= オペレーターで NULL かどうかを調べようとすること。

何が起きる?

SELECT *
FROM students
WHERE age = NULL;

これで年齢が未設定の学生が出ると思いきや…何も返ってこない。なぜ?それは NULL は値じゃないから、普通の比較オペレーターは効かないんだ。SQLの魔法の本にも「NULLは直接比較できない」って書いてあるよ。

どうすればいい?

値が NULL かどうか調べるには IS NULL を使おう:

SELECT *
FROM students
WHERE age IS NULL;

これで年齢が未設定の学生がちゃんと出てくるよ。

ミス2: 集約関数は NULL を無視する(COUNT(*) 以外)

集約関数を使うとき、NULL は自動的に計算から除外される。これで思わぬ結果になることも。

何が起きる?

SELECT AVG(salary) AS avg_salary
FROM employees;

salary カラムに NULL があると、その行は無視されて平均が計算される。これだと平均給与が実際より高く見えちゃうかも。

どう防ぐ?

集約する前に NULL をデフォルト値に置き換えよう。例えば COALESCE() を使う:

SELECT AVG(COALESCE(salary, 0)) AS avg_salary
FROM employees;

これで NULL は0に置き換わって計算されるよ。

ミス3: NULL 同士を比較しちゃう

データベースでは NULL は何にも等しくない。もう一つの NULL ですらね。これ、意外と知らない人多い。

何が起きる?

SELECT *
FROM students
WHERE NULL = NULL;

このクエリも結果は空っぽ。なぜ?SQL的には「値がない」同士は「等しい」とは言えないんだよね。SQLって哲学的だよね。

どうすればいい?

2つの NULL が「等しい」か調べたいなら IS NULL みたいな特別な書き方を使おう。例えば:

SELECT *
FROM students
WHERE first_name IS NULL AND last_name IS NULL;

ミス4: NULL で割り算しちゃう

NULL で割るのは、ただのミスじゃなくて数学的な犯罪(?)みたいなもので、SQLは意味不明な結果 NULL を返してくる。

何が起きる?

SELECT 10 / NULL AS result;

結果は? NULL 。SQLは「何がしたいの?」って感じで無視してくる。

どう防ぐ?

こんな事故を防ぐには COALESCE()NULLIF() を使おう:

SELECT 10 / COALESCE(divisor, 1) AS result
FROM calculations;

このクエリなら divisorNULL でも1で割ることになるよ。

ミス5: NULL でロジックが崩壊する

NULL が論理式に入ると、ロジックが壊れる。例えば TRUE AND NULLTRUE でも FALSE でもなく NULL になる。

何が起きる?

SELECT *
FROM students
WHERE age > 18 OR age = NULL;

この場合、 age > 18 が真な行があっても、 ageNULL の行は結果から外れることがある。なぜ?それは age = NULL の部分が NULL を返すから。

どうすればいい?

ロジック条件では NULL をちゃんと明示的に扱おう:

SELECT *
FROM students
WHERE age > 18 OR age IS NULL;

ミス6: NULL のソートで意外な動き(最も「重い」ミス)

ORDER BY を使うとき、 NULL の扱いにびっくりするかも。PostgreSQLだとデフォルトで昇順なら NULL は最後、降順なら最初に来るよ。

何が起きる?

SELECT product_name, price
FROM products
ORDER BY price;

priceNULL があると、その行はリストの最後に表示される。

どうすれば驚かない?

NULLS FIRSTNULLS LASTNULL の並び順を明示しよう:

SELECT product_name, price
FROM products
ORDER BY price NULLS FIRST;

ミス7: 外部キーと NULL の扱いミス

NULL が外部キーのカラムに入ってると、たまに予想外の動きをすることがある。

何が起きる?

テーブルに外部キーを追加して、外部キーのフィールドを空のまま行を挿入しても、PostgreSQLは何も言わない。これは NULL の値は関連テーブルと照合されないから。

どう扱えばいい?

NOT NULL 制約を使えば、こういうフィールドに NULL を入れられなくできるよ。もしくは、 NULL の値は「孤児」みたいなもので、どの関連テーブルにも属さないって覚えておこう。

関連テーブルや外部キーについては、次のレクチャーで詳しくやるよ :P

1
アンケート/クイズ
条件式、レベル 10、レッスン 4
使用不可
条件式
条件式
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION