🦔

WHERE句と比較演算子[SQL]

に公開

はじめに

こんにちは。
プログラミング初心者wakinozaと申します。
Java勉強中に調べたことを記事にまとめています。

十分気をつけて執筆していますが、なにぶん初心者が書いた記事なので、理解が浅い点などあるかと思います。
間違い等あれば、指摘いただけると助かります。

記事を参考にされる方は、初心者の記事であることを念頭において、お読みいただけると幸いです。

記事のテーマ

  • SQLを学習中で、学んだことをアウトプットしています
  • この記事ではWHERE句とWHERE句で用いる様々な条件式についてまとめていきます

目次

1. WHERE句とは
2. IS NULL / IS NOT NULL演算子
3. LIKE / NOT LIKE演算子
4. BETWEEN演算子
5. IN / NOT IN演算子
6. ANY / ALL演算子
7. AND / OR / NOT演算子

1. WHERE句とは

WHERE句は、SQL文の中で処理対象の行を絞り込むために用います。
このWHEREキーワードから始まる一連の記述を、「WHERE句」と言います。

WHERE句は、4大命令のうち、SELECT・UPDATE・DELETE文で使用できます。

WHEREの後ろには「条件式」を記述するというのが、WHERE句の注意点です。
「条件式」とは、その結果が必ず、「真(true)」か「偽(false)」になる式のことです。
例を挙げてみましょう。

「金額 > 1000」という式は、金額が1000より大きければ真、1000以下なら偽となるため、「条件式」と言えます。WHERE句に使用することができます。

一方、「金額 + 1000」という式は、計算式です。結果は、数字となり、真・偽とはなりません。そのため、WHERE句にも利用できません。

WHERE句で用いることができる「>」や「=」などの記号のことを、「比較演算子」と言います。
比較演算子は、左右にある値を比較して、真か偽の結果を返します。
基本的な比較演算子は、以下の通りです。

比較演算子 働き
= 左右の値が等しい
< 左辺は右辺より小さい
> 左辺は右辺より大きい
<= 左辺は右辺の値以下
>= 左辺は右辺の値以上
<> 左右の値が等しくない

以上・以下の時は、等号の直後に「=」(イコール)を書く点に注意が必要です。

テーブル名:商品テーブル

商品名 個数 価格 発注者名
商品A 10 500 Eさん
商品B 5 300 Gさん
商品C 15 2000 Fさん
商品D 20 1500 Eさん

WHERE句を使って、上のテーブルから指定の行を取り出してみましょう。

SELECT * FROM 商品テーブル
  WHERE 発注者名='Eさん';

上の結果は、以下になります。

商品名 個数 価格 発注者名
商品A 10 500 Eさん
商品D 20 1500 Eさん
SELECT * FROM 商品テーブル
  WHERE 個数>10;

上の結果は、以下になります。

商品名 個数 価格 発注者名
商品C 15 2000 Fさん
商品D 20 1500 Eさん
SELECT * FROM 商品テーブル
  WHERE 価格>=1500;

上の結果は、以下になります。

商品名 個数 価格 発注者名
商品C 15 2000 Fさん
商品D 20 1500 Eさん
SELECT * FROM 商品テーブル
  WHERE 発注者名<>'Eさん';

上の結果は、以下になります。

商品名 個数 価格 発注者名
商品B 5 300 Gさん
商品C 15 2000 Fさん

2. IS NULL / IS NOT NULL 演算子

テーブルに値が格納されていない状態を、「NULL」と言います。
NULLは、数字の0(ゼロ)や空白文字、長さ0の文字列とも異なる存在です。
格納されたデータが「不明」であったり、情報を格納することが「無意味」である状況を示すために用いられます。

NULLかどうかを判定する目的で、=演算子や<>演算子を利用することはできません。
NULLであることを判定するためには「IS NULL」演算子を、NULLでないことを判定するためには「IS NOT NULL」演算子を利用します。

比較演算子 働き
IS NULL NULLであることを判定する
IS NOT NULL NULLでないことを判定する

例を出しましょう。
以下のテーブルがあるとします。

テーブル名:商品テーブル

商品名 個数 価格 発注者名
商品A 10 1000 Eさん
商品B 5 300 (NULL)
商品C 15 2000 Fさん
商品D 20 1500 Eさん
SELECT * FROM 商品テーブル
  WHERE 発注者名 IS NULL;

上の結果は、以下になります。

商品名 個数 価格 発注者名
商品B 5 300 (NULL)
SELECT * FROM 商品テーブル
  WHERE 発注者名 IS NOT NULL;

上の結果は、以下になります。

商品名 個数 価格 発注者名
商品A 10 1000 Eさん
商品C 15 2000 Fさん
商品D 20 1500 Eさん

3. LIKE / NOT LIKE演算子

文字列が「あるパターン」に合致しているかをチェックすることを「パターンマッチング」といいます。
SQLでパターンマッチングを行う際は、 「LIKE」と「NOT LIKE」演算子を使います。
パターンに合致するものを選ぶ場合は「LIKE」演算子を、パターンに合致しないものを選ぶ場合は「NOT LIKE」演算子を使います。

パターンマッチングは、「ワイルドカード」と呼ばれる特殊な文字を使い、検索するパターンを定義します。
ワイルドカードは、以下の文字があります。

ワイルドカード 意味
%(パーセント) 任意の0文字以上の文字列
_(アンダースコア) 任意の1文字
SELECT * FROM 商品テーブル
  WHERE 英単語 LIKE 'A%';

上の例では「A」から始まるすべての文字列を検索します。
マッチする例:Apple, Ant
マッチしない例:Bat, Camel

SELECT * FROM テーブル名
  WHERE ファイル名 LIKE '%.java';

上の例では「.java」で終わるすべての文字列を検索します。
マッチする例:abc.java, defghi.java
マッチしない例:abc.text, abcde.javax

SELECT * FROM テーブル名
  WHERE 住所 LIKE '%東京都%';

上の例では、住所のどこかに「東京都」を含む住所を検索します。
マッチする例: 東京都新宿区, 神奈川県から東京都への転居者, 東京都庁
マッチしない例: 大阪府, 京都府

SELECT * FROM テーブル名
  WHERE コード LIKE '___';

上の例では、3文字のコードを検索します。文字の種類に指定はありません。
マッチする例: A01, X9Z, 123
マッチしない例: A001, AB, 1

もし、パターン文字(%や_)を含んだ文字列を検索したい場合、そのまま記述してもワイルドカードと扱われ、パターン文字列に用いられません。「%」や「_」を、パターン文字列の中で単なる文字として使いたい場合は、エスケープ句を用います。

-- 間違った記述例 
-- 「100%」で終わる文字列を検索したかったが、この状態では「100」を含む文字列を検索してしまう
SELECT * FROM テーブル名
  WHERE パーセント LIKE '%100%';

「%」や「_」を、パターン文字列の中で単なる文字として使いたい場合は、「$(エスケープ句)」を用います。

-- エスケープ句を使った記述例
-- 100%」で終わる文字列が検索できる
SELECT * FROM テーブル名
  WHERE パーセント LIKE '%100$%' ESCAPE '$';

ESCAPE句で指定した文字は「エスケープ文字」となり、パターン文字列中で、エスケープ文字に続く「%」や「_」はただの文字として扱われます。
エスケープ文字には任意の文字を指定できます。

4. BETWEEN演算子

BETWEEN演算子は、ある範囲内に値が収まっているかを判定します。

BETWEEN1 AND2

BETWEEN演算子では、データが「値1以上でかつ値2以下」の場合に真となります。データがちょうど値1や値2の場合も真になります。

テーブル名:商品テーブル

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04
SELECT * FROM 商品テーブル
  WHERE 価格 BETWEEN 1000 AND 2000;

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04

BETWEENは日付にも利用できます。

SELECT * FROM 商品テーブル
  WHERE 搬入日 BETWEEN '2025-02-01' AND '2025-03-31';

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03

5. IN / NOT IN演算子

IN演算子は、カッコ内に列挙した複数の値のいずれかにデータが合致するかを判定する演算子です。=演算子では、1つの値としか比較ができませんが、IN演算子を使えば1度にたくさんの値との比較が可能です。

商品テーブル:商品テーブル

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04
SELECT * FROM 商品テーブル
  WHERE 商品名 IN ('商品B','商品C', '商品D');

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04

NOT IN演算子は、カッコ内に列挙した値のどれとも合致しないことを判定します。

SELECT * FROM 商品テーブル
  WHERE 商品名 NOT IN ('商品B','商品C');

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品D 20 1500 2025-04-04

6. ANY / ALL演算子

「IN」や「NOT IN」演算子は、データが複数の値のどれかと「等しい」かを判定することができました。
もし、複数の値との「大小」を比較したい場合は、「ANY」演算子や「ALL」演算子を利用します。

「ANY」演算子は、値リストのそれぞれと比較していずれかが真なら結果は真となります。
「ALL」演算子は、値リストのそれぞれと比較して全てが真なら結果は真となります。

また、ALLやANYでは、必ずその直前に基本比較演算子をつけます。
基本比較演算子は、1章で説明した「=」「>」「<」「<=」「>=」「<>」の演算子のことです。

基本比較演算子 ANY (1,2・・・)
-- 値リストのそれぞれと比較して、いずれかが真なら真をとなる

基本比較演算子 ALL (1,2・・・)
-- 値リストのそれぞれと比較して、全てが真なら真をとなる

テーブル名:商品テーブル

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04
SELECT * FROM 商品テーブル
  WHERE 価格 < ANY (1000, 1500);

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22

商品Aは1000より小さくないが、1500より小さいので真となり、商品Bは1000より小さいので真となります。
商品Cと商品Dは、1000以上でかつ1500以上なので偽となります。

SELECT * FROM 商品テーブル
  WHERE 価格 < ALL (1000, 1500);

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品B 5 300 2025-02-22

商品Bは1000ともよりも小さく、かつ1500よりも小さいので真となります。
商品Aと商品Cと商品Dは、1000以上または1500以上となるため偽となります。

「ANY」や「ALL」演算子は、挙動が複雑で、他の演算子の方が簡潔に表現できる場合が多いです。

WHERE 価格 < ANY (1000, 1500);

WHERE 価格 < ALL (1000, 1500)

例えば上のように書くより、以下の方が簡潔です。

WHERE 価格 < 1500

WHERE 価格 < 1000

「ANY」や「ALL」演算子は単独で用いるより、副問合せなどの他の仕組みと組み合わせて利用することが多いです。

7. AND / OR / NOT演算子

1つの条件式ではうまく行を絞り込めない場合は、「論理演算子」を用いて複数の条件式を組み合わせることができます。
論理演算子は、以下の通りです。

論理演算子 働き
AND 左右の条件式が両方とも真の場合のみ、真となる
OR 左右の条件式のどちらかが真の場合に、真となる
NOT 真偽を逆転させる

テーブル名:商品テーブル

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04
SELECT * FROM 商品テーブル
  WHERE 個数 <= 15 AND 価格 >= 1000;

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品C 15 2000 2025-03-03
SELECT * FROM 商品テーブル
  WHERE NOT 価格 = 1000;

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品B 5 300 2025-02-22
商品C 15 2000 2025-03-03
商品D 20 1500 2025-04-04

また、複数の論理演算子が利用されている場合は、優先順位に従って処理が行われます。
論理演算子の優先順位は、(1)NOT、(2)AND、(3)ORです。

SELECT * FROM 商品テーブル
  WHERE NOT 価格 > 1500 OR 個数 = 20;

上のコードを実行すると、以下の結果になります。

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22
商品D 20 1500 2025-04-04

まず、NOT演算子から先に評価されます。[価格 > 1500]の結果は[価格 <= 1500]と同等なので、商品A/商品B/商品Dが選択されます。
その後ORが評価され、[商品A/商品B/商品D OR 個数 = 20]は商品A/商品B/商品Dが選択される。

条件式に括弧をつけることで、評価の優先順位を上げることができます。
先ほどのコード例のOR条件式に括弧をつけると結果が変わります。

SELECT * FROM 商品テーブル
  WHERE NOT (価格 > 1500 OR 個数 = 20);

上のコードを実行すると、結果は以下の通りです。

商品名 個数 価格 搬入日
商品A 10 1000 2025-1-10
商品B 5 300 2025-02-22

まず、括弧付きのOR演算子から先に評価され、[価格 > 1500 OR 個数 = 20]は商品C/商品Dとなる
次に、NOT演算子が評価され、結果は商品A/商品Bとなります。

まとめ

  • WHERE句は、SQL文(SELECT, UPDATE, DELETE)において、処理対象の行を絞り込むための条件を記述する句です

  • WHERE句には、結果が真 (true) または偽 (false) のどちらかになる「条件式」を記述します


記事は以上です。
最後までお読みいただき、ありがとうございました。

参考情報一覧

この記事は以下の情報を参考にして執筆しました。

  • [スッキリわかるSQL入門 第3版]
GitHubで編集を提案

Discussion