Categories: SQL言語

SQL│SELECT~WHEREの使い方。検索条件を指定する実例

今回は、テーブルからデータを抽出するときに検索条件を指定するための[WHERE]の使い方について説明します。

大量のデータを格納するRDBMSでは、通常、何の条件も指定せずにすべてのデータを抽出することはなく、目的に応じて抽出の条件指定をすることが普通です。

SQLの[WHERE]を使うことで、Excelのオートフィルタのように様々な条件指定をすることができます。

この記事では、SQLの[WHERE]を使った様々な条件指定の実例について説明します。

SQL_WHEREについて

SQLは、汎用的なプログラミング言語と比較すると、主な命令語は4つしかなく非常に少ないことが特徴です。(SELECT、UPDATE、DELETE、INSERT)

SQLは命令語自体は少なくても修飾語を使うことで、RDBMSに対して様々な命令をすることができます。

WHEREは最も使われる修飾語

その修飾語の中でも最も使用頻度が高いのが、SQLで条件指定をするための[WHERE区]です。

そもそもデータベースとは、扱うデータ量が多いことを理由として導入するものであり、データを参照・抽出する際に、条件指定をせず大量のすべてのデータを抽出することは基本的に行いません。

必然的に今記事で説明する[WHERE区]は、SQLの修飾語の中で最も使用される修飾語なのです。

MySQLに記述されたWHERE区

WHEREの条件指定

Excel等の表計算ソフトをイメージすれば分かりやすいのですが、データを参照・抽出する際の条件指定には、様々な形式があります。

Excelのオートフィルタ(条件指定)

たとえば、下記のような条件です。

  • ある数値以上のレコードを抽出
  • ある数値未満のレコードを抽出
  • ある値に等しいレコードを抽出
  • aかつbに合致するレコードを抽出
  • aまたはbに合致するレコードを抽出

一般に、これらは、比較演算子や論理演算子を組み合わせて条件を具体的に表現することができます。SQLのWHEREも同様で、条件指定に応じた比較演算子・論理演算子をSQL文に記述する必要があります。

SELET、UPDATE、DELETEで使える

当記事では、主にSELECT文にWHERE区を組み合わせる実例で説明しますが、WHERE区は、SELECT以外でもUPDATE、DELETEでも使うことができます。

もう一つの基本文、INSERTでは使うことができません。INSERTは、新規レコードを追加するときに使うSQLであり、既存レコードに条件指定する動作は行わないためです。

WHEREの文法

WHEREは、SELECT ~ FROM ~ WHEREのように、それぞれの基本SQL文の後に記述しますが、WHERE以前の書き方は一緒です。

たとえば、SELECT文でWHEREを使う場合、WHEREの条件指定に関わらず、すべての列を抽出するのであれば、[SELECT * FROM]、特定の列のみ抽出するのであれば[SELECT name FROM]のように、WHERE以前の基本文法は変わりません。

SELECT * FROM Worker WHERE wage_rank < 4;

[SELECT * FROM]、[SELECT name FROM]等の基本文法は一緒

当記事で使うサンプルテーブル

次章以降で、WHEREと比較演算子・論理演算子を組み合わせた様々な条件指定を説明しますが、実例のSQLコードは下記のテーブルを想定して記述します。

テーブル名:Worker
(使用RDBMS:MySQL)

当記事のSQLを実際にお試ししたい方は、上記テーブルの元のcsvを準備していますので、ご自由にお使いください。ダウンロードや使用にあたって、一切の個人情報登録は不要です。(登録されている情報はランダム生成したものであり、実在する人物ではありません)

比較演算子1

まずは、基本的な比較演算子から説明します。未満・超える・以下・以上や等しい・等しくないといった、比較演算子の基本的な記号群です。

<小なり
>大なり
<=以下
>=以上
=等しい
<>または!=等しくない
比較演算子①

< 小なり

「<」は、『左辺は右辺より小さい(未満)』を表す演算子です。たとえば、給与ランク(wage_rank)が4より小さいレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE wage_rank < 4; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank < 4; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE wage_rank < 4;

> 大なり

「>」は、『左辺は右辺より大きい(を超える)』を表す演算子です。たとえば、給与ランク(wage_rank)が3より大きいレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE wage_rank > 3; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank > 3; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE wage_rank > 3;

<= 以下

「<=」は、『左辺は右辺の値以下』を表す演算子です。たとえば、給与ランク(wage_rank)が4以下のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE wage_rank <= 4; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank <= 4; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE wage_rank <= 4;

>= 以上

「>=」は、『左辺は右辺の値以上』を表す演算子です。たとえば、給与ランク(wage_rank)が3以上のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE wage_rank >= 3; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank >= 3; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE wage_rank >= 3;

= 等しい

「=」は、『左辺と右辺は等しい』を表す演算子です。たとえば、給与ランク(wage_rank)が3のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE wage_rank = 3; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank = 3; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE wage_rank = 3;

<>または!= 等しくない

「<>」または「!=」は、『左辺と右辺は等しくない』を表す演算子です。たとえば、給与ランク(wage_rank)が8以外のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE wage_rank <> 8; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank <> 8; --name列のみを抽出

または

SELECT * FROM Worker WHERE wage_rank != 8; --すべての列を抽出
SELECT name FROM Worker WHERE wage_rank != 8; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE wage_rank <> 8;

NULLの判定について

この章では、汎用的な比較演算子(記号)を使って条件指定をするSQLについて説明しましたが、「=」や「<>」を使って対象のデータがNULLかどうかを判定することはできません

たとえば、下記のようなSQLは望んでいる結果を出力してくれません(誤りです)。

× SELECT * FROM Worker WHERE position = NULL;
× SELECT * FROM Worker WHERE position <> NULL;

一見、正しい論理文に思えますが、NULLかどうかの判定は[IS NULL]や[IS NOT NULL]で記述する必要があります。次章で説明します。

比較演算子2

次に、応用的な比較演算子の説明です。空白判定や指定文字を含むかどうかの判定、指定する最小値と最大値の間に収まっているか等、記号ではなく文字で表現する比較演算子です。

IS NULLNULLのときにTRUE
IS NOT NULLNULLではないときにTRUE
LIKE文字列がパターンに合致するときにTRUE
BETWEEN値が〇以上かつ△以下のときにTRUE
IN指定する値のいずれかと一致するときにTRUE
NOT IN指定する値のいずれとも一致しないときにTRUE
比較演算子②
ANY・ALL演算子

他にも、[ANY]や[ALL]という演算子がありますが、少し性質が異なります。そのため、[ANY]と[ALL]については、別記事で説明します。

IS NULL

「IS NULL」は、『NULLの場合にTRUE』を返す演算子です。たとえば、職位(position)がNULLのレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE position IS NULL; --すべての列を抽出
SELECT name FROM Worker WHERE position IS NULL; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE position IS NULL;

IS NOT NULL

「IS NOT NULL」は、『NULLではない場合にTRUE』を返す演算子です。たとえば、職位(position)がNULLではないレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE position IS NOT NULL; --すべての列を抽出
SELECT name FROM Worker WHERE position IS NOT NULL; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE position IS NOT NULL;

LIKE

「LIKE」は、『文字列がパターン合致する場合にTRUE』を返す演算子です。

完全一致と部分一致

一般に、文字列の検索では一言一句マッチする「完全一致」と部分的にマッチする「部分一致」があります。

大量のデータベースから文字列を検索する場合には、圧倒的に「部分一致」を使う機会が多いのですが、LIKE区では下記のワイルドカードを使って部分一致検索を実行します。

_任意の1文字
%任意の0文字以上の文字列
LIKE区のワイルドカード

たとえば、住所(prefecture)に岐阜県という文字列を含んでいるレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE prefecture LIKE '岐阜県%'; --すべての列を抽出
SELECT name FROM Worker WHERE prefecture LIKE '岐阜県%'; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE prefecture LIKE ‘岐阜県’;

当サイトの読者層はワイルドカードの概要をご理解されている方が多いと思うのですが、LIKE区のワイルドカードを用いた部分一致(あいまい検索)については、別記事で詳しく説明します。

BETWEEN

「BETWEEN」は、『値が[基準値1]以上[基準値2]以下の場合にTRUE』を返す演算子です。たとえば、雇用年月日(hire_date)が2020-05-01以降かつ2020-09-30以下のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE hire_date BETWEEN '2020-05-01' AND '2020-09-30'; --すべての列を抽出
SELECT name FROM Worker WHERE hire_date BETWEEN '2020-05-01' AND '2020-09-30'; --name列のみを抽出

基準値が日付型の場合には、上記のように両端に「’」(シングルクォーテーション)が必要です。

下の結果_SELECT * FROM Worker WHERE hire_date BETWEEN ‘2020-05-01’ AND ‘2020-09-30’;

IN

「IN」は、『指定する値のいずれかと一致する場合にTRUE』を返す演算子です。たとえば、所属部署(department)が2か4のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE department IN (2,4); --すべての列を抽出
SELECT name FROM Worker WHERE department IN (2,4);; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE department IN (2,4);

NOT IN

「IN」は、『指定する値のいずれとも一致しない場合にTRUE』を返す演算子です。たとえば、所属部署(department)が2か4以外のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE department NOT IN (2,4); --すべての列を抽出
SELECT name FROM Worker WHERE department NOT IN (2,4); --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE department NOT IN (2,4);

論理演算子

最後は、論理演算子の説明です。SQL文に論理演算子を組み合わせることで、複数の条件指定をすることが可能になります。

AND両方の式がTRUEのときにTRUE
OR片方の式がTRUEのときにTRUE
NOTTRUEならFALSE,FALSEならTRUE
論理演算子
論理演算子の複数条件

論理演算子については、優先順位や3つ以上の条件を組み合わせる場合など、複雑化する傾向がありますので、詳しくは別記事で説明します。

AND

「AND」は、『両方の式がTRUEの場合にTRUE(かつ)』を返す演算子です。たとえば、雇用年月日(hire_date)が2020-7-31以前かつ所属部署が1のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE hire_date <= '2020-07-31' AND department = 1; --すべての列を抽出
SELECT name FROM Worker WHERE hire_date <= '2020-07-31' AND department = 1; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE hire_date <= ‘2020-07-31’ AND department = 1;

OR

「OR」は、『片方の式がTRUEの場合にTRUE(または)』を返す演算子です。たとえば、所属部署が5または給与ランク5以上のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE department = 5 or wage_rank >= 5; --すべての列を抽出
SELECT name FROM Worker WHERE department = 5 or wage_rank >= 5; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE department = 5 or wage_rank >= 5;

NOT

「NOT」は、『TRUEの場合にFALSE、FALSEの場合にTRUE(または)』を返す演算子です。給与ランク(wage_rank)が8以外のレコードを抽出したいときには、下記のようにSQL文を実行します。

SELECT * FROM Worker WHERE NOT wage_rank = 8; --すべての列を抽出
SELECT name FROM Worker WHERE NOT wage_rank = 8; --name列のみを抽出
下の結果_SELECT * FROM Worker WHERE NOT wage_rank = 8;

論理演算子の[NOT]は、比較演算子の[<>]または[!=]と同じ結果を返します。

WHEREの補足

前章までに、WHERE区で比較・論理演算子を使う場合のSQL文について説明しました。

この記事の最後に、WHEREの初歩的な概念・使い方について補足します。

概要:主キーの重要性

基本的に、RDBMSのテーブル構造はExcelのようにデフォルトの行番号に基づいて順序付けがされている訳ではありません。

よって、SELECT・UPDATE・DELETE等とWHEREを組み合わせて対象の1行を特定するためには、主キー(PRIMARY KEY)を使うことが基本になります。

社員マスタで例えると、重複を許さない「社員番号」が主キーになるでしょう。

主キーがない場合には、氏名・生年月日・電話番号・住所等、複合的な条件で個人を特定するしかありません。

2016年に導入された[マイナンバー制度]は、要は国民ひとりひとりに主キーを振った制度です。個人のマイナンバーは、番号だけで個人を特定できる主キーです。

複数列の抽出

今回の記事では、WHEREを使って条件に合致したすべての列を抽出した実画面を掲載しましたが、本文で説明した通り、SQL文のWHERE以前の文法は変わりませんので、抽出する列は自由に指定することができます。

テーブル名:Worker
(使用RDBMS:MySQL)

たとえば、上記のテーブルから所属部署(department)が2の社員番号(worker_id)と社員名(name)と所属部署(department)を抽出したい場合には、下記のSQLを実行します。

SELECT worker_id,name,department FROM Worker WHERE department = 2;
下の結果_SELECT worker_id,name,department FROM Worker WHERE department = 2;

なお、この例では、所属部署(department)を条件指定のキーとしましたが、所属部署自体を抽出することは必須ではありません。下記のように、所属部署をキーにして、社員番号(worker_id)と社員名(name)のみを抽出することも可能です。

SELECT worker_id,name FROM Worker WHERE department = 2;
下の結果_SELECT worker_id,name FROM Worker WHERE department = 2;

あとがき

今回は、SQLのWHERE区について、比較演算子・論理演算子と組み合わせて、条件指定をするためのSQL文の基本について記事にしました。

本文で説明した通り、データベースは大量のデータを格納する基地になりますので、WHERE区を使った条件指定は、RDBMSの日々の運用で日常的に使う基本文になります。

今記事では基本的な内容に留めていますので、いくつかの演算子についての詳しい情報は、改めて当サイトで発信します。

Analytics沖縄

データサイエンス・機械学習・ディープラーニングを本格的に研究するフリーランスエンジニア。 「Google データアナリティクス プロフェッショナル」の認定証を取得済み。 この分野は専門知識がなければ理解し辛い情報が多いのですが、当サイトでは初学者も意識して発信していきますので、ご関心があればぜひご覧ください。

Recent Posts

MySQLの日付型や時刻型で使う関数のフォーマット指定子

今回は、MySQLの日付型や時…

4か月 ago

SQL│文字列を日付型に変換するTo_Date・Convert

今回は、SQLで文字列を日付型…

4か月 ago

SQL│文字列型CHAR・VARCHARの違いと使い分けを解説

今回は、SQLのデータ型のうち…

4か月 ago

SQL|通貨型MONEY・SMALLMONEYの使い所は?

今回は、SQLの通貨型MONE…

5か月 ago