SQLのwhere句についてまとめています。
where句での複数条件指定、範囲指定、あいまい検索、サブクエリを使った条件指定、動的に条件式を切り替える方法について紹介します。
SQLのwhere句は条件指定で絞り込みが可能
SQLのwhere句では条件を指定して、抽出データの絞り込みが可能です。
以下の例は、employees(社員テーブル)から、emp_no(社員番号)が20000のデータを抽出する例です。
mysql> select * from employees where emp_no = 20000; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 20000 | 1961-09-14 | Jenwei | Matzke | F | 1990-11-29 | +--------+------------+------------+-----------+--------+------------+ 1 row in set (0.00 sec)
where句で演算子を使って複数の条件を指定
where句では、各種演算子を使って複数の条件指定が可能です。
- A and B … 条件Aと条件Bを同時に満たす
- A or B … 条件Aか条件Bを満たす
- not A … 条件A以外
# first_name=Georgiとlast_name=Facelloを同時に満たすレコードを抽出 mysql> select * from employees where first_name = 'Georgi' and last_name = 'Facello'; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | | 55649 | 1956-01-23 | Georgi | Facello | M | 1988-05-04 | +--------+------------+------------+-----------+--------+------------+ 2 rows in set (0.10 sec) # first_name=Georgiとlast_name=Facelloのどちらかを満たすレコードを抽出 mysql> select * from employees where first_name = 'Georgi' or last_name = 'Facello' limit 10; +--------+------------+------------+------------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+------------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | | 10327 | 1954-04-01 | Roded | Facello | M | 1987-09-18 | | 10909 | 1954-11-11 | Georgi | Atchley | M | 1985-04-21 | | 11029 | 1962-07-12 | Georgi | Itzfeldt | M | 1992-12-27 | | 11430 | 1957-01-23 | Georgi | Klassen | M | 1996-02-27 | | 12157 | 1960-03-30 | Georgi | Barinka | M | 1985-06-04 | | 12751 | 1964-07-06 | Nahum | Facello | M | 1995-01-09 | | 15220 | 1957-08-03 | Georgi | Panienski | F | 1995-07-23 | | 15346 | 1959-09-26 | Kirk | Facello | F | 1991-12-07 | | 15660 | 1956-01-13 | Georgi | Hartvigsen | M | 1994-10-13 | +--------+------------+------------+------------+--------+------------+ 10 rows in set (0.00 sec) # first_nameがGeorgi以外のレコードを抽出 mysql> select * from employees where not first_name = 'Georgi' limit 10; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 | | 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 | | 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 | | 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 | | 10006 | 1953-04-20 | Anneke | Preusig | F | 1989-06-02 | | 10007 | 1957-05-23 | Tzvetan | Zielinski | F | 1989-02-10 | | 10008 | 1958-02-19 | Saniya | Kalloufi | M | 1994-09-15 | | 10009 | 1952-04-19 | Sumant | Peac | F | 1985-02-18 | | 10010 | 1963-06-01 | Duangkaew | Piveteau | F | 1989-08-24 | | 10011 | 1953-11-07 | Mary | Sluis | F | 1990-01-22 | +--------+------------+------------+-----------+--------+------------+ 10 rows in set (0.00 sec)
さらに括弧を使って、それぞれの条件を入れ子構造にしたり、複数の条件を同時に指定することも可能です。
【関連記事】
▶SQLの条件指定はWHERE句 andやor、notの論理演算子で複数条件指定できる
where句で範囲指定をするにはbetween
等号や不等号を使わず、絞り込み条件に範囲指定を使いたい場合はbetweenを使います。
以下は、emp_no(社員番号)が20000~20005のレコードをemployees(社員テーブル)から抽出するSQLです。
SELECT * FROM employees where emp_no between 20000 and 20005; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 20000 | 1961-09-14 | Jenwei | Matzke | F | 1990-11-29 | | 20001 | 1962-05-16 | Atreye | Eppinger | M | 1990-04-18 | | 20002 | 1955-12-25 | Jaber | Brender | M | 1988-01-26 | | 20003 | 1953-04-11 | Munehiko | Coors | F | 1991-02-07 | | 20004 | 1952-03-07 | Radoslaw | Pfau | M | 1995-11-24 | | 20005 | 1956-02-20 | Licheng | Przulj | M | 1992-07-17 | +--------+------------+------------+-----------+--------+------------+ 6 rows in set (0.00 sec)
注意点は、A以上B以下という指定のみ可能で、A未満とかBより大きいという指定はできない点。
【関連記事】
▶SQL betweenで範囲指定するサンプルコード 速度アップにもつながる?
where句でサブクエリを使って条件指定
固定値ではなく、サブクエリでデータベース内から取得したデータを条件指定に使うには、サブクエリを使います。
サブクエリとは、以下のSQLのwhere句にあるカッコで囲まれたSQLです。
SELECT first_name, last_name, birth_date FROM employees a WHERE birth_date = ( select min(birth_date) from employees b ) +------------+--------------+------------+ | first_name | last_name | birth_date | +------------+--------------+------------+ | Jouni | Pocchiola | 1952-02-01 | | Moni | Decaestecker | 1952-02-01 | | Eishiro | Kuzuoka | 1952-02-01 | | Kiyokazu | Whitcomb | 1952-02-01 | | Ronghao | Schaad | 1952-02-01 | | Supot | Remmele | 1952-02-01 | +------------+--------------+------------+ 6 rows in set (0.17 sec)
この例では、以下の部分がサブクエリとなります。
select min(birth_date) from employees b
このSQLは、employees(社員テーブル)からbirth_date(誕生日)が最も古い社員を抽出しています。テーブル名にaとかbがついているのは、テーブルの自己結合をおこなうために同一のテーブルを別テーブルとして扱うためのものです。
なお、上記の場合はサブクエリの結果が一件のみにならない場合はエラーになりまs.
【関連記事】
▶SQL where句のサンプルコード集 ワイルドカードやサブクエリを使った複雑な条件指定
where句であいまい検索をおこなうには、like
where句であいまい検索をおこなうにはlikeを使います。ワイルドカード文字を使った条件指定が可能です。
以下は、first_name(姓名の名)がAで始まり、last_name(姓名の姓)がSで始まるレコードををemployees(社員テーブル)から抽出する例です。
SELECT * FROM employees WHERE first_name like 'A%' and last_name not like 'S%' +--------+------------+------------+--------------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+--------------+--------+------------+ | 10006 | 1953-04-20 | Anneke | Preusig | F | 1989-06-02 | | 10033 | 1956-11-14 | Arif | Merlo | M | 1987-03-18 | | 10035 | 1953-02-08 | Alain | Chappelet | M | 1988-09-05 | | 10036 | 1959-08-10 | Adamantios | Portugali | M | 1992-01-03 | | 10039 | 1959-10-01 | Alejandro | Brender | M | 1988-01-19 | | 10059 | 1953-09-19 | Alejandro | McAlpine | F | 1991-06-26 | | 10062 | 1961-11-02 | Anoosh | Peyn | M | 1991-08-30 | | 10091 | 1955-10-04 | Amabile | Gomatam | M | 1992-11-18 | | 10094 | 1957-05-25 | Arumugam | Ossenbruggen | F | 1987-04-18 | | 10103 | 1953-11-26 | Akemi | Birch | M | 1986-12-02 | +--------+------------+------------+--------------+--------+------------+ 10 rows in set (0.00 sec)
%が1文字以上の文字列にマッチするワイルドカード文字になります。
【関連記事】
▶【SQL】LIKE句の基本的な使い方~複数検索する場合の方法まで解説
where句の条件を動的に切り替えるにはcase式を使用
where句の条件を格納されたデータに応じて動的に切り替えるにはcase式を使います。
以下は、gender(性別)がM(男性)ならbirth_date、gender(性別)がF(女性)ならhire_dateが1980年1月1日以降のデータを10件抽出する例です。
mysql> select * from employees where case when gender="M" then birth_date when gender="F" then hire_date end > '1980-01-01' limit 10; +--------+------------+------------+------------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+------------+--------+------------+ | 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 | | 10006 | 1953-04-20 | Anneke | Preusig | F | 1989-06-02 | | 10007 | 1957-05-23 | Tzvetan | Zielinski | F | 1989-02-10 | | 10009 | 1952-04-19 | Sumant | Peac | F | 1985-02-18 | | 10010 | 1963-06-01 | Duangkaew | Piveteau | F | 1989-08-24 | | 10011 | 1953-11-07 | Mary | Sluis | F | 1990-01-22 | | 10017 | 1958-07-06 | Cristinel | Bouloucos | F | 1993-08-03 | | 10018 | 1954-06-19 | Kazuhide | Peha | F | 1987-04-03 | | 10023 | 1953-09-29 | Bojan | Montemayor | F | 1989-12-17 | | 10024 | 1958-09-05 | Suzette | Pettey | F | 1997-05-19 | +--------+------------+------------+------------+--------+------------+ 10 rows in set (0.00 sec)
【関連記事】
▶SQLのwhereはcase式で条件切替が可能 条件の有り・無しを記述できる
case~endで囲った部分が、それぞれの条件によりthen以下に記述した条件に動的に変わります。caseは入れ子構造にすることもでき、かなり複雑な条件も組み込むことができます。
まとめ
- SQLのwhere句は絞り込み条件を指定できる。複数指定も可能
- where句では範囲指定、あいまい検索、サブクエリでの条件指定が可能
- where句でcase式を組み合わせると、条件をデータに合わせて動的に変化させられる