SQLのwhere句でinを使った条件指定についてまとめています。
SQLのwhere句の条件指定でinを使う
where句でinを使って、値のどれかに等しいデータを抽出可能です。
以下の例では、emp_no(社員番号)が10001または10005または10010のどれかに等しいデータを抽出します。
mysql> select * from employees -> where emp_no in (10001,10005,10010); +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | | 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 | | 10010 | 1963-06-01 | Duangkaew | Piveteau | F | 1989-08-24 | +--------+------------+------------+-----------+--------+------------+ 3 rows in set (0.00 sec)
【関連記事】
▶SQL in句のサンプルコード集 複数カラムの指定方法とは?
対象のデータが2つや3つ程度ならば演算子orを使って記述できますが、対象になる値が多くなってくるとinを使って記述したほうがスッキリしますし、コードをパッと見て直感的にわかりやすいですね。
where句で複数カラムの条件指定でinを使う
inを使って、複数カラムをセットにして値の比較が可能です。
以下は、employees(社員テーブル)のfirst_name(姓名の名)、last_name(姓名の姓)の組み合わせが「Geoff Birnbaum」「Sanjai Marrevee」「Udo Harbusch」のデータを抽出します。
mysql> select * from employees where (first_name, last_name) in ( ( 'Geoff', 'Birnbaum' ), ('Sanjai','Marrevee'),('Udo','Harbusch') ); +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 20006 | 1953-09-21 | Geoff | Birnbaum | F | 1988-05-04 | | 20026 | 1953-03-25 | Sanjai | Marrevee | F | 1991-09-23 | | 20039 | 1952-06-07 | Udo | Harbusch | F | 1987-09-19 | | 48485 | 1962-07-06 | Geoff | Birnbaum | M | 1992-06-16 | +--------+------------+------------+-----------+--------+------------+ 4 rows in set (0.14 sec)
上記の例は2カラムをセットにしていますが、3カラム、4カラム…と増やしていくことも可能です。
where句でサブクエリの条件指定でinを使う
条件指定が値の集合ではなく、別テーブルからデータを取得して動的に変化する場合は、inのカッコ内にサブクエリを指定します。
以下は、titles(役職テーブル)から、役職が「Staff」の社員情報を、employees(社員テーブル)から取得する例です。to_date=’9999-01-01’は、最新の役職を取得するための条件です。
select * from employees where emp_no in ( select emp_no as emp_no from titles where titles.emp_no = employees.emp_no and title='Staff' and to_date='9999-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 | | 10016 | 1961-05-02 | Kazuhito | Cappelletti | M | 1995-01-27 | | 10019 | 1953-01-23 | Lillian | Haddadi | M | 1999-04-30 | | 10071 | 1958-01-21 | Hisao | Lipner | M | 1987-10-01 | | 10077 | 1964-04-18 | Mona | Azuma | M | 1990-03-02 | | 10093 | 1964-06-11 | Sailaja | Desikan | M | 1996-11-05 | | 10112 | 1963-08-13 | Yuichiro | Swick | F | 1985-10-08 | | 10132 | 1956-12-15 | Ayakannu | Skrikant | M | 1994-10-30 | | 10148 | 1957-10-04 | Douadi | Azumi | M | 1995-10-10 | | 10154 | 1957-01-17 | Abdulah | Thibadeau | F | 1990-12-12 | +--------+------------+------------+-------------+--------+------------+ 10 rows in set (0.15 sec)
inとサブクエリを組み合わせる場合、注意点は2つあります。
1つは、サブクエリの返す列の数をinの左辺の数と合わせること。上記の例ではサブクエリは1つの列のみ返すクエリにする必要があります。
2つ目は、パフォーマンスの問題。サブクエリとinを組み合わせると、レスポンスが悪くなるケースがあります。このような場合はin+サブクエリではなく、left joinなどを使った結合に書き換えることで速度が改善することがあります。
まとめ
- where句でinを使うと値の集合を絞り込み条件に指定できる
- inの左辺を括弧で囲み、複数カラムを対象にすることも可能
- in+サブクエリを条件式で使用する場合は、返す列数とパフォーマンスに注意する