「MySQLで必要なデータだけを正確に取り出したい」
「WHERE句を書いているのに、なぜか想定と違う結果が返る」
「UPDATEやDELETEで誤って全件更新してしまうのが怖い」
このような悩みを持つ方にとって、WHERE句の理解はSQLスキルの分水嶺です。
WHERE句は単なる「絞り込み機能」ではありません。
検索精度・データ整合性・パフォーマンス・安全性すべてに直結する、最重要構文です。
本記事では、
- WHERE句の基本構文
- 比較演算子・BETWEEN・AND/OR・IN・LIKEの使い分け
- NULLや型変換の落とし穴
- 実務でのパフォーマンス最適化
- UPDATE・DELETEで事故を防ぐ設計
- インデックス設計との関係
まで網羅的に解説します。
初心者が理解できる丁寧さと、実務経験者が納得する深さを両立した内容でお届けします。
WHERE句とは?|データ取得条件を指定する中核構文
WHERE句とは、SELECT・UPDATE・DELETEなどで対象行を条件指定するための構文です。
SELECT 列名
FROM テーブル名
WHERE 条件;
WHERE句がない場合、テーブルの全行が対象になります。
これはSELECTだけでなく、UPDATEやDELETEでも同様です。
UPDATE users SET status = 'inactive';
上記はWHEREがないため、全件更新されます。
実務では致命的な事故になり得ます。
WHERE句の評価の仕組み
WHERE句は「行ごと」に評価されます。
- 条件が TRUE → 結果に含まれる
- FALSE → 含まれない
- NULL → 含まれない
この「NULLは除外される」という特性が、多くのバグの原因になります。
公式ドキュメントも参照すると理解が深まります:
MySQL公式マニュアル(WHERE句)
https://dev.mysql.com/doc/refman/8.0/en/where-optimization.html
WHERE句の基本構文と実行例
全件取得
条件付き取得
SELECT * FROM friends
WHERE address = 'Tokyo';
数値条件
SELECT * FROM friends
WHERE age < 30;
重要なのは、条件によって結果件数がどう変化するかを必ず確認することです。
比較演算子の使い方(=, !=, >, <, >=, <=)
主な比較演算子
| 演算子 |
意味 |
| = |
等しい |
| != または <> |
等しくない |
| > |
より大きい |
| < |
より小さい |
| >= |
以上 |
| <= |
以下 |
実務で多いミス
「20歳以上」なのか「20歳を含まない」のかで結果が変わります。
要件を必ず日本語で明確にしてからSQLに落とすことが重要です。
範囲指定(BETWEEN)の正しい使い方
SELECT * FROM friends
WHERE age BETWEEN 20 AND 29;
ポイント
- BETWEENは両端を含む
- 20以上30未満にしたい場合は
WHERE age >= 20 AND age < 30;
日付での注意点
WHERE created_at BETWEEN '2026-02-01' AND '2026-02-28';
日時型の場合、終端の扱いで漏れが発生します。
より安全なのは:
WHERE created_at >= '2026-02-01'
AND created_at < '2026-03-01';
複数条件(AND / OR)の使い分け
AND条件
SELECT * FROM friends
WHERE address = 'Osaka'
AND age >= 20;
→ 条件を「絞る」
OR条件
SELECT * FROM friends
WHERE address = 'Tokyo'
OR address = 'Osaka';
→ 条件を「広げる」
実務のコツ
- ANDを増やすと件数は減る
- ORを増やすと件数は増える
ANDとORの優先順位と括弧
SQLでは
AND > OR
の優先順位です。
address = 'Tokyo'
OR address = 'Osaka'
AND age >= 20;
これは
address = 'Tokyo'
OR (address = 'Osaka' AND age >= 20);
と解釈されます。
意図を明確にするには必ず括弧を使いましょう。
(address = 'Tokyo' OR address = 'Osaka')
AND age >= 20;
IN / NOT IN の使い方
IN
SELECT * FROM friends
WHERE address IN ('Tokyo', 'Osaka');
ORを並べるより可読性が高いです。
NOT INの落とし穴(NULL問題)
対象列にNULLがある場合、結果が想定とずれることがあります。
NULLを含む可能性がある場合は:
WHERE address NOT IN ('Tokyo', 'Osaka')
AND address IS NOT NULL;/* Your code... */
と明示しましょう。
LIKEによるあいまい検索
ワイルドカード
パフォーマンスの注意
LIKE 'abc%' → インデックスが使われやすい
LIKE '%abc%' → フルスキャンになりやすい
大規模データでは特に注意が必要です。
詳細はMySQL公式ドキュメント参照:
https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html
NULLの扱い(IS NULL / IS NOT NULL)
WHERE deleted_at IS NULL;
NULLは
では比較できません。
これはSQL標準仕様です。
参考:PostgreSQL公式ドキュメント(NULLの説明)
https://www.postgresql.org/docs/current/functions-comparison.html
型の違いと暗黙の型変換
文字列はシングルクォートで囲みます。
address = 'Tokyo'
age = 30
MySQLは暗黙的に型変換を行いますが、
これが予期しない一致を生むことがあります。
実務では列の型と値の型を必ず揃えることが重要です。
実務で差がつく:パフォーマンス最適化
1. インデックスを意識する
WHERE句の列にインデックスがあるかどうかで、
数百万件の差が出ます。
EXPLAIN SELECT * FROM users
WHERE email = 'test@example.com';
EXPLAINで実行計画を確認しましょう。
2. 関数を使うとインデックスが効かない
WHERE DATE(created_at) = '2026-02-14';
これはインデックスが使われにくいです。
代わりに:
WHERE created_at >= '2026-02-14'
AND created_at < '2026-02-15';
UPDATE・DELETEでの安全なWHERE句
必ずSELECTで確認
SELECT * FROM users
WHERE status = 'inactive';
結果確認後に
UPDATE users
SET flag = 1
WHERE status = 'inactive';
LIMITを使う
DELETE FROM users
WHERE status = 'test'
LIMIT 10;
本番環境ではトランザクション利用も推奨です。
WHERE句でよくある失敗まとめ
- WHEREを書き忘れる
- AND/ORの括弧ミス
- BETWEENの境界誤認
- NOT IN + NULL問題
- 型の不一致
- インデックス未考慮
WHERE句で使う演算子まとめ
- 比較:=, !=, >, <, >=, <=
- 範囲:BETWEEN
- 複数条件:AND / OR
- 集合:IN / NOT IN
- あいまい検索:LIKE
- NULL判定:IS NULL
まとめ|MySQLのWHERE句を正しく使えるかがSQL力を決める
WHERE句は単なる条件指定ではありません。
- 検索精度を決める
- 更新・削除の安全性を担保する
- パフォーマンスを左右する
- インデックス設計と密接に関わる
正確な条件式を書く力は、
エンジニアとしての基礎体力そのものです。
次にやるべきこと
- 実際のテーブルでEXPLAINを使ってみる
- AND/ORの括弧パターンを複数試す
- インデックスの有無で速度比較する
- UPDATE/DELETE前に必ずSELECTで検証する習慣をつける
データベース設計・パフォーマンス最適化に本気で向き合いたい方へ
ここまで読み込んでいる方は、
単にSQLを「書ける」レベルではなく、
安全で高速なデータ設計に興味を持っている方だと思います。
私たちは、
- 大規模トラフィック環境でのMySQL最適化
- インデックス設計
- クエリチューニング
- データモデリング改善
に本気で取り組むエンジニアチームです。
データベース設計やSQLチューニングを突き詰めたい方、
実務で通用する技術力を高めたい方を歓迎しています。
もしあなたが、
「データベースを武器にできるエンジニアになりたい」
そう考えているなら、ぜひ私たちの採用ページもご覧ください。
一緒に、正確で強いシステムを作っていきましょう。