SQLiteは軽量で扱いやすいデータベースとして、多くのアプリやシステムで活用されています。特に開発の初期段階やモバイルアプリのローカルDBとしての需要は高く、学んでおく価値は十分にあります。
しかし、SQLiteにおける「NULL」の扱いには注意が必要です。SQL初心者だけでなく、経験者でもNULLに関する誤解によって思わぬバグを招くことがあります。
この記事では、SQLiteにおけるNULLの基本的な扱い方から、IS NULL
や IS NOT NULL
の使い方、=
との違い、注意点まで、具体例を交えて3000文字以上で詳しく解説します。
NULLとは何か?SQLiteにおける基本的な意味
SQLiteにおける「NULL」は、値が存在しないことを示す特別な状態です。これは「空文字(”)」や「0」などとは意味が異なり、値そのものが未定義であることを意味します。
たとえば、以下のようなテーブルがあるとします:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
);
このテーブルにデータを挿入する際に、emailを省略するとどうなるでしょうか?
INSERT INTO users (name) VALUES ('佐藤');
この場合、email
カラムには NULL
が自動的に格納されます。つまり、「メールアドレスが空」ではなく「メールアドレスがまだ設定されていない」という状態になります。
IS NULL と IS NOT NULL の使い方
NULLは通常の比較演算子(例:=
や!=
)では正しく比較できません。NULLは何とも等しくない(NULL != NULL)という性質を持っているためです。
そのため、NULLかどうかを調べるには、IS NULL
または IS NOT NULL
を使用する必要があります。
例:IS NULL を使った検索
SELECT * FROM users WHERE email IS NULL;
これは、「メールアドレスが未設定(NULL)のユーザーを取得する」クエリです。普通に email = NULL
と書いても、何も返ってきません。
例:IS NOT NULL を使った検索
SELECT * FROM users WHERE email IS NOT NULL;
これは、「メールアドレスが設定されているユーザーを取得する」クエリです。
NULLと比較演算子の違いに注意
多くの人が間違いやすいのが、=
や!=
を使ってNULLを比較しようとするケースです。
-- 間違った書き方(結果は常にfalse)
SELECT * FROM users WHERE email = NULL;
このような書き方をしても、期待通りに動作しません。なぜなら、NULL = NULL
の結果は「不明(UNKNOWN)」であり、WHERE句で評価されると「false」として扱われてしまうためです。
代わりに、次のように書くのが正解です:
-- 正しい書き方
SELECT * FROM users WHERE email IS NULL;
NULLの扱いに関する応用的な例
COALESCE関数でNULLを他の値に置き換える
SQLiteでは、COALESCE
関数を使うことで、NULLを特定の値に置き換えることができます。
SELECT name, COALESCE(email, '未登録') AS email_display FROM users;
このクエリでは、emailがNULLであれば「未登録」という文字列に置き換えて表示してくれます。
NULLを含む条件での並べ替え
ソート時にNULLを先に出したい、または後に出したい場合は、以下のように書くことができます:
-- NULLを最後にする
SELECT * FROM users ORDER BY email IS NULL, email;
-- NULLを最初にする
SELECT * FROM users ORDER BY email IS NOT NULL, email;
このように IS NULL
を使うことで、NULLの並び順も制御可能です。
WHERE句だけじゃない!JOIN句でのNULLへの注意点
外部結合(LEFT JOINなど)を使う場合にも、NULLは頻繁に登場します。
例:LEFT JOINで関連データが存在しない場合
SELECT u.name, o.order_date
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
このクエリで、注文のないユーザーは order_date
が NULL
になります。
このとき、「注文がないユーザーだけを表示したい」と思って次のように書いてしまうと間違いです:
-- 間違い:o.order_date = NULL
SELECT u.name FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.order_date = NULL;
正しくはこうです:
-- 正解:o.order_date IS NULL
SELECT u.name FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.order_date IS NULL;
NULLを扱う際の設計上の注意点
SQLiteでNULLを使うこと自体は悪くありませんが、設計時には以下のような注意点もあります。
- NOT NULL制約を必要なカラムにしっかり設定する。
- ロジックで
IS NULL
を使いすぎると、クエリの読みやすさが下がるため、必要最小限に。 - NULLをデフォルトにしないことで、より意図が明確なテーブル設計が可能。
また、集計系の関数でもNULLの扱いには注意が必要です。
sqlコピーする編集するSELECT AVG(score) FROM test_results;
このようなクエリでは、NULLの値は平均値の計算から除外されます。NULLを0とみなしたい場合は次のように書き換えます:
sqlコピーする編集するSELECT AVG(COALESCE(score, 0)) FROM test_results;
まとめ:NULLとIS NULLを正しく使いこなすことがSQLite操作の基本
SQLiteにおけるNULLは、「値が未定義」であることを示す重要な概念です。しかし、その特殊性ゆえに、正しく扱わないと意図しない動作につながることがあります。
- NULLは
=
では比較できない IS NULL
やIS NOT NULL
を使うこと- 表示や計算には
COALESCE
が便利 - 外部結合の際にもNULLの考慮が必要
これらのポイントを理解しておくことで、SQLiteをより安全に、そしてスマートに使いこなすことができるでしょう。ぜひ日々の開発や学習の参考にしてください。