SQLを使用してデータベースから特定のデータを効率的に抽出するためには、検索条件を自在に操るスキルが不可欠です。
その中心となるのが、複数の条件を組み合わせるための論理演算子です。
AND、OR、NOTといった演算子を正しく理解し、それらが処理される優先順位を把握することは、正確なクエリを作成するための第一歩となります。
本記事では、SQLの論理演算子の基本から、複雑な条件指定をミスなく行うための優先順位のルールまでを詳しく解説します。
論理演算子とは? SQLにおける基本的な役割
SQLにおける論理演算子は、WHERE句などで複数の条件を組み合わせて、行が抽出対象に含まれるかどうかを判定するために使用されます。
これらの演算子は、指定された条件を評価し、その結果が真(TRUE)であるデータのみを返します。
リレーショナルデータベースでは、データの比較結果が「真(TRUE)」、「偽(FALSE)」、そして「不明(UNKNOWN)」の3つの状態を持つ三値論理に基づいています。
三値論理は、データが存在しないことを示す「NULL」が含まれる場合に非常に重要な考え方となります。
論理演算子を使いこなすことで、単一の条件だけでは表現できない複雑なフィルタリングを実装できます。
主な論理演算子には、「AND(かつ)」、「OR(または)」、「NOT(〜でない)」の3種類が存在します。
SQLで扱う真理値の基礎
演算子の解説に入る前に、SQLがどのように条件を評価しているかを理解しておく必要があります。
通常、条件式は score >= 80 のように記述され、これが成り立つ場合にのみデータが抽出されます。
しかし、対象の列にNULLが含まれている場合、比較結果はTRUEでもFALSEでもなく、UNKNOWN(不明)となります。
SQLの論理演算子は、このUNKNOWNを含めた論理評価を行うため、プログラム言語の論理演算とは若干挙動が異なる点に注意してください。
AND演算子:すべての条件を満たすデータの抽出
AND演算子は、複数の条件がすべて「真(TRUE)」である場合にのみ、その行を抽出対象とします。
日本語では「かつ」や「および」と訳され、検索条件を絞り込みたい場合に多用されます。
例えば、「東京都に住んでいる」かつ「年齢が20歳以上」といった、より限定的なデータを取得する際に使用します。
以下のサンプルコードは、商品の在庫数が10個以上であり、かつ単価が1,000円以下の商品を抽出する例です。
-- 在庫数が10以上、かつ単価が1000円以下の商品を検索
SELECT product_name, stock, price
FROM products
WHERE stock >= 10
AND price <= 1000;
product_name | stock | price
-------------+-------+-------
消しゴム | 50 | 100
ノート | 25 | 200
このクエリでは、stock >= 10 と price <= 1000 の両方の条件をクリアしたデータだけが表示されます。
もし、どちらか一方でも条件を満たさない場合、その行は結果に含まれません。
AND演算子を複数繋げることで、3つ以上の条件を同時に満たす行を探すことも可能です。
AND演算子とNULLの関係
AND演算子を使用する際、条件のいずれかにNULLが含まれる場合の評価に注意が必要です。
「TRUE AND UNKNOWN」の結果は「UNKNOWN」となります。
「FALSE AND UNKNOWN」の結果は「FALSE」となります。
SQLのWHERE句は、評価結果が「TRUE」の場合のみデータを返すため、結果がUNKNOWNになった行は表示されません。
OR演算子:いずれかの条件を満たすデータの抽出
OR演算子は、指定した複数の条件のうち、少なくとも1つが「真(TRUE)」であればその行を抽出します。
日本語では「または」や「もしくは」と表現され、検索範囲を広げたい場合に利用されます。
例えば、「会員ランクがゴールド」または「購入金額が10万円以上」のユーザーを抽出する場合などに適しています。
以下のコードは、部署名が「営業部」または「総務部」に所属する社員を取得する例です。
-- 営業部または総務部の社員を検索
SELECT employee_name, department
FROM employees
WHERE department = '営業部'
OR department = '総務部';
employee_name | department
--------------+-----------
田中 太郎 | 営業部
佐藤 次郎 | 総務部
鈴木 花子 | 営業部
OR演算子を使うことで、複数のキーワードのいずれかに合致するデータを一度に取得できます。
ただし、条件を増やすほどヒットするデータの件数は増える傾向にあります。
OR演算子を使用する際の注意点
OR演算子においても、NULLが関わる評価ルールを把握しておくべきです。
「TRUE OR UNKNOWN」の結果は「TRUE」になります。
「FALSE OR UNKNOWN」の結果は「UNKNOWN」になります。
つまり、いずれかの条件が確実にTRUEであれば、他の条件がNULL(UNKNOWN)であってもその行は抽出されます。
NOT演算子:条件の反転と否定
NOT演算子は、直後に記述した条件式の評価結果を反転させる役割を持ちます。
「TRUE」は「FALSE」に、「FALSE」は「TRUE」に変換されます。
ただし、「UNKNOWN」を反転させても「UNKNOWN」のままである点には注意してください。
「〜ではないデータ」を探したい場合に非常に便利です。
以下の例では、退職フラグが立っていない(現役の)社員を抽出しています。
-- 退職していない(is_retiredが1ではない)社員を検索
SELECT employee_name
FROM employees
WHERE NOT is_retired = 1;
employee_name
--------------
田中 太郎
鈴木 花子
NOT演算子は、単独で使用するよりも、他の演算子や関数(IN、BETWEEN、LIKE、IS NULLなど)と組み合わせて使われることが多い演算子です。
NOT演算子の組み合わせ例
NOT IN を使えば、「指定したリストに含まれない値」を簡単に検索できます。
NOT LIKE を使えば、「特定のパターンに一致しない文字列」を探せます。
IS NOT NULL は、データが入っている行だけを絞り込む際によく使われる定石のフレーズです。
演算子の優先順位(実行順序)のルール
複数の論理演算子を1つのWHERE句に記述する場合、それらが評価される順番はあらかじめ決まっています。
この優先順位を誤解していると、意図しないデータが抽出されたり、必要なデータが漏れたりする原因になります。
SQLにおける論理演算子の基本的な優先順位は以下の通りです。
| 順位 | 演算子 | 説明 |
|---|---|---|
| 1 | ( ) | カッコ内の式(最優先) |
| 2 | NOT | 否定演算子 |
| 3 | AND | 論理積 |
| 4 | OR | 論理和 |
ここで最も重要なのは、「ANDはORよりも先に評価される」という点です。
数学の計算において「足し算(+)よりも掛け算(×)が優先される」ルールと似ています。
優先順位による結果の違い:具体例
例えば、「(部署が営業部 または 総務部)であり、かつ、役職が部長」というデータを取得したいケースを考えます。
以下のクエリは、期待通りの動きをしません。
-- 誤った記述例(優先順位を考慮していない)
SELECT employee_name, department, job_title
FROM employees
WHERE department = '営業部'
OR department = '総務部'
AND job_title = '部長';
このクエリでは、まず優先順位の高い department = '総務部' AND job_title = '部長' が評価されます。
その結果、「営業部の全社員」と「総務部の部長」が抽出されてしまいます。
「営業部の平社員」も結果に含まれてしまうため、本来の目的とは異なる結果となります。
優先順位を制御するカッコ ( ) の活用
演算子の優先順位を明示的に変更し、意図した通りの論理構成にするにはカッコ ( ) を使用します。
カッコで囲まれた部分は、他のどの演算子よりも先に評価されるようになります。
先ほどの例を正しく書き換えると、以下のようになります。
-- 正しい記述例(カッコでOR条件を優先させる)
SELECT employee_name, department, job_title
FROM employees
WHERE (department = '営業部' OR department = '総務部')
AND job_title = '部長';
employee_name | department | job_title
--------------+-----------+-----------
田中 太郎 | 営業部 | 部長
佐藤 次郎 | 総務部 | 部長
このようにカッコを用いることで、まず「営業部か総務部のどちらかである」という集合を作り、その中から「部長である」人を絞り込むという論理が成立します。
論理演算子が3つ以上組み合わさる複雑なクエリでは、可読性を高めるためにもカッコを使用することが推奨されます。
可読性とメンテナンス性の向上
カッコは優先順位を制御するだけでなく、クエリを読む人間に対しても「どの条件がひとかたまりなのか」を伝える効果があります。
将来的にクエリを修正する際、カッコが適切に配置されていれば、ロジックの意図を一目で理解できます。
たとえ優先順位のルール上カッコが不要な場面であっても、論理的な区切りを明確にするためにあえて記述する手法は実務でも一般的です。
実務で役立つ論理演算のベストプラクティス
SQLの論理演算を効率的かつ正確に扱うための、いくつかのテクニックを紹介します。
まず、OR条件が大量に並ぶ場合は、IN 演算子への書き換えを検討しましょう。
WHERE col = 'A' OR col = 'B' OR col = 'C' と書くよりも、WHERE col IN ('A', 'B', 'C') と書くほうが視認性が高く、ミスも減ります。
また、否定の条件(NOT)を多用すると、論理が複雑になりやすく、インデックスが効率的に利用されない場合があることも覚えておいてください。
データベースの種類によっては、NOT を含む条件式はフルスキャンを誘発し、パフォーマンスを低下させることがあります。
ド・モルガンの法則を活用した簡略化
複雑な条件を整理する際、数学の「ド・モルガンの法則」を応用できる場合があります。
「NOT (A AND B)」は「(NOT A) OR (NOT B)」と等価です。
「NOT (A OR B)」は「(NOT A) AND (NOT B)」と等価です。
人間にとって理解しやすい論理構成に書き換えることで、バグの混入を防ぐことができます。
まとめ
SQLの論理演算子であるAND、OR、NOTは、データを自在に操るための基礎でありながら、非常に奥が深い要素です。
すべての条件を満たすAND、いずれかを満たすOR、結果を反転させるNOTの特性を正確に理解しましょう。
特に演算子の優先順位(NOT > AND > OR)は、複雑なクエリを書く際の落とし穴になりやすいため注意が必要です。
意図しない挙動を防ぐためには、積極的にカッコ ( ) を使用して評価順序を明示することが、正確で読みやすいSQLを書くためのコツです。
三値論理やNULLの挙動も含め、これらのルールを習得することで、データベースから必要な情報を正確に、そして効率的に取り出すことができるようになるでしょう。
