SQLで複数の値の何れかに合致する行を検索したい場合、ANDとORで値の数だけ列挙するやり方は非効率です。IN句を使って検索することで、冗長な記述を省略できます。
本記事では、SQLにおけるIN句を使った検索方法について解説します。IN句の応用的な使い方やIN句とLIKE句を使った曖昧検索に加え、生成AIを用いた作業効率化の方法も掲載しているので、SQLの可読性を上げたい方は、ぜひ参考にしてみてください。
- IN句は列挙したリストに合致する行を抽出できる
- サブクエリからの検索や複数カラムの条件指定もできる
- DBMSごとに文字列の引用符やリストに列挙できる上限数は異なる
SQLで使うIN検索とは
IN句は、複数の条件を指定した検索をまとめられるクエリです。IN句に列挙したリストの何れかに合致する行を抽出できます。以下の例を見てみましょう。
【USERテーブル】
USERID | NAME | TYPE |
001 | YAMADA | A |
002 | SATO | B |
003 | TANAKA | A |
004 | SUZUKI | C |
005 | KATOそ | D |
006 | NAKATA | B |
USERテーブルから、TYPEがA、C、Dの何れかの行を抽出したい場合、IN句を使わないと以下のSQLになります。
SELECT * FROM USER WHERE TYPE = ‘A’ OR TYPE = ‘C’ OR TYPE = ‘D’;
「 OR TYPE = 」の部分が冗長化しており、値の数だけ記述するのは大変ですよね。そこで、IN句を使うことで、以下のように簡略化することが可能です。
SELECT * FROM USER WHERE TYPE IN ( ‘A’ , ‘C’ , ‘D’);
IN句の使い方
それでは、IN句の基本的な構文を紹介します。
SELECT * FROM [テーブル名] WHERE [カラム名] IN ([値1,値2,値3,…]);
()で括った中に抽出したい値のリストを列挙するのみです。リストの値の何れかに合致する行を全て抽出します。WHERE句内でIN句以外の条件も加えたい場合には、IN句と条件をANDまたはORで連結させましょう。
SQLでIN句を使う2つの場面
IN句は、1つのSQL内で複数回記述する場合があるほど、使用頻度が高いです。IN句は主に、以下の2つの場面で使用します。
- 指定した複数の値のリストから検索する
- サブクエリの結果から検索する
以下のテーブルを例に、詳しく見ていきましょう。
【STUDENTテーブル】
NAME | COUNTRY | AGE |
YAMADA | JAPAN | 18 |
SATO | AMERICA | 17 |
TANAKA | CANADA | 18 |
SUZUKI | JAPAN | 16 |
KATO | INDIA | 16 |
NAKATA | CANADA | 18 |
【STATEテーブル】
COUNTRY | GROUP | RANK |
JAPAN | A | 1 |
AMERICA | B | 3 |
CANADA | B | 4 |
INDIA | A | 2 |
指定した複数の値のリストから検索する
まずは、先述している通り、複数の値のリストから該当する行を検索する場面です。
例1)STUDENTテーブルからCOUNTRYがJAPANまたはCANADAの行を取得する
【SQL】
SELECT * FROM STUDENT WHERE COUNTRY IN (‘JAPAN’,’CANADA’);
【抽出結果】
NAME | COUNTRY | AGE |
YAMADA | JAPAN | 18 |
TANAKA | CANADA | 18 |
SUZUKI | JAPAN | 16 |
NAKATA | CANADA | 18 |
例2)STUDENTテーブルからAGEが16または17の行を取得する
【SQL】
SELECT * FROM STUDENT WHERE AGE IN (16,17);
【抽出結果】
NAME | COUNTRY | AGE |
SATO | AMERICA | 17 |
SUZUKI | JAPAN | 16 |
KATO | INDIA | 16 |
IN句の()に列挙する値は、SQLの基本的な規則と同様に、文字列ならばシングルクオーテーションで囲みます。
サブクエリの結果から検索する
IN句で指定できるのは、値のリストだけではありません。SQLの中に入れ子でSQLを記述することを指すサブクエリ(副問い合わせ)も、IN句で指定できます。
例3)STUDENTテーブルからSTATEテーブルでRANKが2以下のCOUNTRYの行を抽出する
【SQL】
SELECT * FROM STUDENT
WHERE COUNTRY IN (SELECT COUNTRY FROM STATE WHERE RANK <= 2);
【抽出結果】
NAME | COUNTRY | AGE |
YAMADA | JAPAN | 18 |
SUZUKI | JAPAN | 16 |
KATO | INDIA | 16 |
上記のSQLでは、サブクエリが先に実行され、IN句のリストにJAPANとINDIAが入ります。その後、IN句の判定が実行され、COUNTRYがJAPANまたはINDIAに該当する行が抽出されるという流れです。
万が一、サブクエリの結果が1つしか該当しなかったとしても、問題なくIN句は実行されます。IN句に指定する値は、単一でも問題ありません。
IN句の応用的な2つの使い方
IN句を使い、「単一カラムが複数の値の何れかに該当する」という条件指定をマスターした方は、以下の2つの応用的な使い方にもチャレンジしてみてください。
- IN句の否定形「NOT IN句」
- 複数カラムのAND・OR条件を置き換える
それぞれの使い方について、詳しく解説します。
IN句の否定形「NOT IN句」
A OR Bを指定するIN句の否定形が、NOT IN句です。A OR Bの否定は全否定になり、AもBも含まない行を抽出します。具体的な例は、以下のとおりです。
例4)STUDENTテーブルからCOUNTRYがJAPANかCANADA以外の行を抽出する
【SQL】
SELECT * FROM STUDENT WHERE COUNTRY NOT IN (‘JAPAN’,’CANADA’);
【抽出結果】
NAME | COUNTRY | AGE |
SATO | AMERICA | 17 |
KATO | INDIA | 16 |
NOT IN句はテーブル内を全検索しているため、レコード数が多いテーブルから検索する際には、処理が重たくなります。NOT EXISTSで代用する方法もあるので、状況に応じて使い分けましょう!
複数カラムのAND・OR条件を置き換える
IN句は、複数カラムの検索も可能です。ANDやORを使って書くと、以下のように長くなるSQLをコンパクトにまとめられます。
【IN句を使わない場合】
SELECT FROM [テーブル名]
WHERE ( [カラムA] = [値1] AND [カラムB] = [値2] ) OR ( [カラムA] = [値3] AND [カラムB] = [値4] ) … ;
【IN句を使った場合】
SELECT FROM [テーブル名]
WHERE ( [カラムA] , [カラムB] ) IN ( ( [値1 , 値2] ) , ( [値3 , 値4] ) , …) ;
IN句を含むSQL文の生成に長けた方であれば、アプリ開発における顧客情報や商品情報の管理ができるでしょう。
SQLでIN句との併用ができないLIKE句
データベースの操作を行っていると、複数の値の曖昧検索を行いたい状況に遭遇することがあります。そこで、以下のように曖昧検索ができるLIKE句とIN句を併用して解決!と思われる方も、多いのではないでしょうか。
SELECT * FROM [テーブル名] WHERE [カラムA] LIKE IN ( [ %値1,%値2,%値3 …] ) ;
しかし、IN句とLIKE句は同時には使用できません。
LIKE句+IN句の代わりになる記述方法とは
上記で示したLIKE句とIN句を併用した記述を正しく修正すると、以下のようになります。
SELECT * FROM [テーブル名]
WHERE [カラムA] LIKE %値1 OR [カラムA] LIKE %値2 OR [カラムA] LIKE %値2 …;
「OR [カラムA] LIKE 」の冗長箇所を簡略化したい場合は、以下の3つの演算子や関数を併用することで、正規表現によるパターンマッチングで代用することも可能です。
- REGEXP演算子
- CONCAT関数
- GROUP_CONCAT関数
SQLのIN検索に関するよくある質問
早速、IN句を使って検索を試みようとした時に、以下のような疑問が浮かんだ方も多いのではないでしょうか。
- MySQLとOracleでIN句の記述方法は違う?
- IN句で指定できる値に上限はある?
- IN句とEXISTS句の違いは?
それぞれのよくある質問について、詳しく解説します。
MySQLとOracleでIN句の記述方法は違う?
代表的なDBMS(データベース管理システム)であるMySQLとOracleにおいて、IN句の記述方法に違いはありません。
ただし、ダブルクォーテーションで囲った場合に、MySQLでは文字列定数として認識されるのに対し、Oracleでは引用識別子として認識されます。そのため、以下のようなSQLは、MySQLでは実行できますが、Oracleでは実行できないので注意しましょう。
SELECT * FROM STUDENT WHERE COUNTRY IN (“JAPAN”,”CANADA”);
IN句で指定できる値に上限はある?
大規模なテーブルからIN検索を行う場合、リストに指定する値が多くなることがあるでしょう。IN句で使用できる値の上限は、DBMSによって異なります。
MySQLは最大パケットサイズの制限が許す限り、IN句に値を列挙することが可能です。一方で、Oracleは最大数が1000件と決まっており、それ以上記述すると以下のエラーが発生します。
【エラーメッセージ】
ORA-01795: リストに指定できる式の最大数は1000です。
IN句とEXISTS句の違いは?
IN句と混同しやすいクエリがEXISTS句です。IN句は、条件に合致する行を全て抽出するのに対し、EXISTS句は、条件に合致する行が存在するか否かのみを返します。
SELECT * FROM STUDENT
WHERE COUNTRY IN (SELECT COUNTRY FROM STATE WHERE RANK <= 2);
上記をEXISTSで書き換えたSQLは、以下のとおりです。
SELECT S.* FROM STUDENT S WHERE EXISTS (SELECT 1 FROM STATE R WHERE R.RANK <= 2 AND R.COUNTRY = S.COUNTRY); |
生成AI×SQL
SQLに慣れていない方は、以下のような悩みを抱えることもあるでしょう。
「土台がない状態で1からSQLを書くのが難しい…」
「作ったSQLが合っているのか確認したい」
そのような悩みは、生成AIを活用することで解決します!
たとえば、「STUDENTテーブルからCOUNTRYがJAPANまたはCANADAの行を取得して」という指示を生成AI(ChatGPT)に出してみます。
すると、指示を送ったわずか5秒以内にIN句を使った正しいSQLが生成されました。
生成AIが書いたSQLを雛形として参考にすることで、初心者でもスムーズにSQLが書けるようになるのです。また、実際に作ったSQLの正誤判定を生成AIに投げかける、という活用方法もあるでしょう。
ぜひ、生成AIを活用し、業務の効率化を図ってみてください!
生成AIとは?
近年、市場規模が右肩上がりで拡大している生成AIは、業界の働き方を変革する可能性を秘めています。生成AIとは、機械学習の一種で、学習したデータから新しいデータを創出する技術のことです。
2023年初頭に生成AIの一種であるChatGPTが爆発的な話題を呼び、実際に触ってみたという方も多いのではないでしょうか。生成AIの技術は年々飛躍しており、業務に取り入れることで、コード生成や文章作成等の普段の作業をAIに代行してもらうことが可能になります。
まとめ
本記事では、SQLにおけるIN句を使った検索方法について解説してきました。
IN句を使うことで、列挙したリストに合致する行を抽出したり、サブクエリの結果から検索したりすることが可能です。DBMSによって、文字列を囲む引用符やリストに指定できる値の上限が異なるので、DBMSに合った記述方法を習得しましょう!
市場価値が拡大している生成AIを用いることで、SQLの作成も効率化できます。SQLの雛形をAIに作成してもらうことで時短になるだけでなく、追記したSQLの構文ミスの検出も可能です。
そして、生成AIを用いることで、さらにSQLが簡単になるため、ぜひ本記事を参考に試してみてください。