SQL WHERE: AND・OR・NULL で行を絞り込む

SQL WHERE 句は、条件式でテーブル行を絞り込む SQL 句です。SQL クエリの WHERE 句では、述語が TRUE と評価された行だけが一致します。FALSE と NULL/UNKNOWN はどちらも除外されます。この三値論理は、NULL まわりで WHERE の挙動が想定外になる最も一般的な原因です。

行絞り込みの SQL WHERE 句の例

出力:

ここに出力が表示されます...

出力:

+------------+----------+-------+
| name       | category | price |
+------------+----------+-------+
| キーボード | 電子機器 | 49.99 |
| マウス     | 電子機器 | 25.0  |
+------------+----------+-------+
2 row(s)

この例の仕組み

  1. CREATE TABLEINSERT で、2 つのカテゴリにまたがる 4 行の products テーブルを作成します。
  2. SQL クエリ WHERE 句の category = '電子機器' AND price < 100 は、2 つの条件を AND で結合しています。行が表示されるには両方が TRUE である必要があります。
  3. 「モニター」は電子機器ですが価格が 299.00 のため、価格条件で除外されます。「ノート」はカテゴリ条件を満たしません。両方の述語を満たすのは「キーボード」と「マウス」だけです。

SQL WHERE 句とは?

SQL WHERE 句は、各行に個別に適用されるブールフィルターです。データベースは候補行ごとに式を評価し、結果が TRUE の行だけを残します。FALSE または NULL を返す式は破棄されます。WHERE は GROUP BY と集計関数より前に動作するため、HAVING と役割が異なります。

SQL WHERE 句でよくある間違い

間違い: 列を = で NULL と比較する。

誤り:

WHERE category = NULL

正解:

WHERE category IS NULL

理由: = NULL は UNKNOWN と評価され、WHERE は UNKNOWN の行を除外します。IS NULL または IS NOT NULL を使います。

間違い: ANDOR を括弧なしで混在させる。

誤り:

WHERE category = 'オフィス' OR category = '電子機器' AND price < 50

正解:

WHERE (category = 'オフィス' OR category = '電子機器') AND price < 50

理由: ANDOR より結合が強いため、意図どおりに評価させるには括弧が必要です。

WHERE と HAVING の違い

WHEREHAVING
グループ化前の個別行を絞り込む集計後のグループを絞り込む
集計関数を参照できないCOUNTSUM などを参照できる
GROUP BY に渡す行数を減らす最終結果のグループ数を減らす

原則: 集計前に行を除外するなら WHERE、集計後にグループを除外するなら HAVING を使います。WHERE で早めに絞り込むと、集計ステップの処理量を減らせます。

パフォーマンスの考慮点

インデックス付き列に対する WHERE 述語は、全表走査をインデックス参照に変えられます。列を関数で包む (LOWER(name), DATE(created_at)) とオプティマイザがインデックスを使えなくなるため、代わりに比較値を変換します。AND でつながる条件では、述語の列順に合わせた複合インデックスが最も高い効果を出します。OR 条件は別々のインデックス走査をマージする実行計画になりやすく、同じインデックス上の AND より遅くなることが多いです。

セキュリティメモ

WHERE 条件は、ユーザー入力を SQL 文字列に連結せず、必ずパラメータ化クエリで組み立てます。動的な列名が必要な場合は、厳密な許可リストで検証します。IN (...) リストではプレースホルダーを生成し、各値をバインドします。UPDATE や DELETE を実行する前に、同じ WHERE 句の SELECT で対象行を必ず確認してください。

FAQ

SQL の WHERE と HAVING の違いは何ですか?

WHERE は GROUP BY の前に行を絞り込み、HAVING はその後に集計済みグループを絞り込みます。WHERE では COUNT()SUM() のような集計関数を参照できません。1 つのクエリで両方を使うこともできます。WHERE で入力行を減らし、次に HAVING でグループ結果を絞り込みます。

WHERE 句で = NULL が動かないのはなぜですか?

SQL は TRUE、FALSE、UNKNOWN の三値論理を使います。NULL との比較はすべて UNKNOWN を返し、WHERE は UNKNOWN の行を捨てます。NULL 判定には IS NULL を使います。データベースによっては、NULL 安全な等価比較として IS NOT DISTINCT FROM も使えます。

WHERE 句の条件の記述順はパフォーマンスに影響しますか?

SQL 標準は評価順を保証しておらず、多くのオプティマイザは内部で述語順を並べ替えます。条件は読みやすい順で書いて問題ありません。実際の性能を左右するのは、記述順ではなく、どの列にインデックスがあるかと各述語の選択性です。