Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLで情報を検索にかける際、LIKEやINなどは頻繁に使用します。

データベースの情報を広く検索する場合には、このLIKEとINを同時に使いたくなる場面も出てくると思いますが、SQLはこれを許可していません。

そこで今回はLIKEとINを同時に使いたい場合にはどのようにすれば良いか、LIKEとINの基本的使い方と共に解説してみたいと思います。

LIKEの基本

LIKEは曖昧検索をする際によく使われる命令句です。

前方一致検索や後方一致検索、または完全一致検索など様々な検索に柔軟な対応が可能なため、データベースの情報を取得する際には大いに役に立ちます。

まずはこのLIKEについて基本的な使い方を見てみましょう。

LIKEの記述

LIKEの基本的な記述は次の通りです。

SELECT [カラム名], ... FROM [テーブル名] WHERE [カラム名] LIKE [曖昧検索の条件];

実曖昧検索の条件では「%(パーセント)」ワイルドカードを使用し、前方一致検索、後方一致検索、部分一致検索、完全一致検索の四つからどの検索を使用するか指定します。

コードを見てもらえばすぐにわかると思いますので、実際のコードを見てみましょう。

なおデータベーステーブルに入っているデータは次の通りです。

MariaDB [sample]> SELECT * FROM sample_table;
+----+------+-----+------------+
| id | name | age | birth      |
+----+------+-----+------------+
|  1 | 山田 |  29 | 1990-05-27 |
|  2 | 田中 |  25 | 1994-10-22 |
|  3 | 中元 |  30 | 1989-04-01 |
|  4 | 宮原 |  35 | 1984-03-18 |
|  5 | 鈴木 |  18 | 2001-06-15 |
|  6 | 竹下 |  23 | 1996-02-21 |
|  7 | 本田 |  26 | 1993-07-17 |
|  8 | 中井 |  29 | 1990-08-03 |
|  9 | 徳井 |  34 | 1985-05-15 |
| 10 | 野間 |  40 | 1979-11-06 |
+----+------+-----+------------+
10 rows in set (0.000 sec)

このテーブルから「田」の付く名前のみ抽出する場合には、LIKE句を使って次のように記述します。

MariaDB [sample]> SELECT * FROM sample_table WHERE name LIKE "%田%";
+----+------+-----+------------+
| id | name | age | birth      |
+----+------+-----+------------+
|  1 | 山田 |  29 | 1990-05-27 |
|  2 | 田中 |  25 | 1994-10-22 |
|  7 | 本田 |  26 | 1993-07-17 |
+----+------+-----+------------+
3 rows in set (0.001 sec)

「LIKE “%田%”」とすることで、部分一致検索で田が付く名前を全て出力しています。

これがLIKEの基本的な使い方です。

INの基本

では次にINの使い方についても簡単に解説していきます。

IN句は複数の検索をする場合に使用される命令句です。

ただし曖昧検索というわけではなく、完全一致検索のみとなります。

記述は次の通りとなります。

SELECT [カラム名], ... FROM [テーブル名] WHERE [カラム名] IN([値1, 値2, 値3, ...]);

検索したい値を全て条件に指定するだけのシンプルな記述です。

ただしIN句は、プログラムによると思いますが、基本形で使用されることはあまり無いように見受けます。

ではどのように使われるかという部分については、恐らくサブクエリとして「IN句を使いSELECTで取得したデータをアップデートなどで使用する」という方法ではないでしょうか。

文章では言っている意味がよく分からないと思いますので、こちらもコードで解説してみたいと思います。

今回のサンプルで使用するデータベーステーブルは次の通りです。

// sample_table
MariaDB [sample]> SELECT * FROM sample_table;
+----+--------+-----+------------+----------+
| id | name   | age | birth      | group_id |
+----+--------+-----+------------+----------+
|  1 | 山田   |  29 | 1990-05-27 |        3 |
|  2 | 田中   |  25 | 1994-10-22 |        3 |
|  3 | 中元   |  30 | 1989-04-01 |        2 |
|  4 | 宮原   |  35 | 1984-03-18 |        2 |
|  5 | 鈴木   |  18 | 2001-06-15 |        4 |
|  6 | 竹下   |  23 | 1996-02-21 |        3 |
|  7 | 本田   |  26 | 1993-07-17 |        3 |
|  8 | 中井   |  29 | 1990-08-03 |        3 |
|  9 | 徳井   |  34 | 1985-05-15 |        2 |
| 10 | 野間   |  40 | 1979-11-06 |        1 |
+----+--------+-----+------------+----------+
10 rows in set (0.000 sec)

// generation_table
MariaDB [sample]> SELECT * FROM generation_table;
+----+------------+
| id | group_name |
+----+------------+
|  1 | 40代       |
|  2 | 30代       |
|  3 | 20代       |
|  4 | 10代       |
+----+------------+
4 rows in set (0.000 sec)

例えば、この二つのテーブルを使って、20代のみを取得できるようなクエリを組んでみます。

MariaDB [sample]> SELECT * FROM sample_table
    ->                  WHERE group_id IN(
    ->                          SELECT id FROM generation_table
    ->                          WHERE id = 3
    ->                  );
+----+------+-----+------------+----------+
| id | name | age | birth      | group_id |
+----+------+-----+------------+----------+
|  1 | 山田 |  29 | 1990-05-27 |        3 |
|  2 | 田中 |  25 | 1994-10-22 |        3 |
|  6 | 竹下 |  23 | 1996-02-21 |        3 |
|  7 | 本田 |  26 | 1993-07-17 |        3 |
|  8 | 中井 |  29 | 1990-08-03 |        3 |
+----+------+-----+------------+----------+
5 rows in set (0.000 sec)

IN句をサブクエリとして使えば、このような方法で検索をすることが出来ます。

LIKE句とIN句を同時に使いたい場合

ではここからが本記事の本題です。

まず結果から言うと、残念ながらLIKE句とIN句は同時使用が認められていないため不可能です。

ただし、別のクエリをいくつか複合的に使用することで、同じような結果を得ることは可能です。

※今回はLIKE句とIN句を同時使用したい場合の解説を行うため、その他のクエリに関しては解説を省略します。

この解説を行うため、次のようなテーブルを用意します。

MariaDB [sample]> SELECT * FROM item_table;
+----+---------------------+-----------+-------+
| id | name                | item_code | type  |
+----+---------------------+-----------+-------+
|  1 | Juice Orange(500ml) | djf500    | Drink |
|  2 | Bread Strawberry    | fbf01     | Food  |
|  3 | RiceBall Tuna       | frw01     | Food  |
|  4 | Bread Egg Sandwich  | fbo01     | Food  |
|  5 | Juice Apple(500ml)  | djf500    | Drink |
|  6 | Carbonated Water    | dwo1000   | Drink |
+----+---------------------+-----------+-------+
6 rows in set (0.000 sec)

MariaDB [sample]> SELECT * FROM code_table;
+----+-------------+
| id | code        |
+----+-------------+
|  1 | djf500-160  |
|  2 | dwo1000-200 |
|  3 | dwo500-100  |
|  4 | fbf01-100   |
|  5 | fbo-200     |
|  6 | frw01-130   |
+----+-------------+
6 rows in set (0.000 sec)

item_tableには商品と分類、code_tableには商品分類及び価格が入っています。

このcode_tableから、item_tableに存在するドリンクのみ抽出する場合で考えてみましょう。

REGEXPで正規表現の条件検索

まずドリンクに分類されるものはitem_tableの中には3種類あります。

この三つをitem_codeカラムを使ってcode_tableで参照させるには、REGEXP演算子を利用する事で解決します。

MariaDB [sample]> SELECT * FROM code_table
    ->                  WHERE code REGEXP('(^djf500-.*)|(^dwo500-.*)|(^dwo1000-.*)');
+----+-------------+
| id | code        |
+----+-------------+
|  1 | djf500-160  |
|  2 | dwo1000-200 |
|  3 | dwo500-100  |
+----+-------------+
3 rows in set (0.000 sec)

正規表現でパターンマッチングを行うことで、codeカラムから該当する全てのcodeを抽出できます。

ただし今回は結果としてitem_tableからドリンクのみを抽出させるため、REGEXPに記述している正規表現自体を別の方法で作る必要があります。

そこで次の方法を併用します。

CONCAT関数とGROUP_CONCAT関数を使用して文字列を作成する

CONCAT関数は、文字列を連結させ一つの文字列に組み替えるための関数です。

またGROUP_CONCAT関数は、指定したカラムに不l組まれる値を連結して表示させるための関数です。

これら二つの関数を使用し、先ほどREGEXPで記述した正規表現文字列を作成していきます。

MariaDB [sample]> SELECT CONCAT('(^', (
    ->                  SELECT GROUP_CONCAT(item_code SEPARATOR '-.*)|(^')
    ->                  FROM item_table
    ->                  WHERE type = 'Drink'
    ->          ), '-.*)');

+--------------------------------------------+
| (^djf500-.*)|(^djf500-.*)|(^dwo1000-.*)    |
+--------------------------------------------+

作成した正規表現文字列をREGEXPと組み合わせる

最後に、CONCAT関数とGROUP_CONCAT関数を使って作成した正規表現文字列をREGEXPのサブクエリとして使用します。

MariaDB [sample]> SELECT * FROM code_table
    ->                  WHERE code REGEXP(
    ->                          SELECT CONCAT('(^', (
    ->                                  SELECT GROUP_CONCAT(item_code SEPARATOR '-.*)|(^')
    ->                                  FROM item_table
    ->                                  WHERE type = 'Drink'
    ->                          ), '-.*)')
    ->                  );
+----+-------------+
| id | code        |
+----+-------------+
|  1 | djf500-160  |
|  2 | dwo1000-200 |
+----+-------------+
2 rows in set (0.000 sec)

これでitem_tableにあるドリンクに対応しているcodeを、code_tableから全て抽出することが出来ます。

まとめ

いかがでしたか?

今回は若干難しい内容にはなっていたと思いますが、このようにクエリによっては組み合わせが出来ないものでも、別のクエリをいくつか組み合わせることで代替させることが可能です。

しかしこれに気付くにはまず、出来るだけ多くのクエリを頭に入れておく必要があります。

現在SQLを学習されている方に特に言えることですが、どんなクエリが存在するのか、またそれらにはどういう作用があるのかを一通り調べてみると面白いかもしれません。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。