LoginSignup
32
24

More than 5 years have passed since last update.

[MySQL] LIKEとINを組み合わせて使いたい場合はREGEXPとGROUP_CONCATとCONCATを使う

Last updated at Posted at 2018-09-11

MySQLで、以下のような検索がしたい。

  • あるフィールドの値が、他のテーブルからの検索結果の値から始まる

サンプルデータ

商品マスター(items)

name item_code type
あんぱん abc01 パン
ジャムぱん def02 パン
カレーぱん ghy03 パン
梅干しおにぎり qwe01 ごはん
こんぶおにぎり asd02 ごはん
鮭おにぎり zxc03 ごはん

注文(orders)

ID order_code(商品コード-価格)
order01 abc01-80
order02 abc01-160
order03 ghy03-120
order04 zxc03-100
order05 asd02-400
order06 qwe01-240

検索要求

注文から、以下の条件を満たすレコードを抽出したい。

  • 注文コードの値が、「商品マスター」において「パン」の分類に該当する商品コードから始まる

IN と LIKE を組み合わせたい

パッと考えると以下のようなSQLを書きたくなる。

SELECT *
FROM orders
WHERE order_code LIKE IN ('abc01-%', 'def02-%', 'ghy03-%');

しかし、LIKEとINを同時に使うことはできない。

手法

検索条件に正規表現を使う

この場合、正規表現で検索条件を作れる REGEXP を利用することができる。

SELECT *
FROM orders
WHERE order_code REGEXP ('(^abc01-.*)|(^def02-.*)|(^ghy03-.*)');

しかし本来 (^abc01-.*)|(^def02-.*)|(^ghy03-.*) の箇所は別の検索結果から導き出さないといけない。

そこで、サブクエリを使って検索結果から正規表現文字列を作成する。

CONCAT()

  • CONCAT( 文字列1, 文字列2, ・・・文字列N ) で、各引数の文字列を連結したひとつの文字列を取得できる。
  • CONCAT( 文字列1, (SELECTサブクエリ), 文字列2) で、「文字列1サブクエリの結果文字列2」というふうな取得もできる。
SELECT CONCAT('あん', 'ぱん');

↓
あんぱん

GROUP_CONCAT()

  • GROUP_CONCAT(フィールド名 SEPARATOR 連結文字列) FROM TABLE_NAME WHERE 検索条件
    で、検索結果を連結文字列でつなげた文字列を得ることができる。
SELECT GROUP_CONCAT(item_code SEPARATOR ',')
FROM items
WHERE type = 'パン';

↓
abc01,def02,ghy03

CONCAT() と GROUP_CONCAT() とサブクエリを使って正規表現文字列を作る

SELECT CONCAT('(^', (
  SELECT GROUP_CONCAT(item_code SEPARATOR '-.*)|(^')
  FROM items
  WHERE type = 'パン';
), '-.*)');

↓
(^abc01-.*)|(^def02-.*)|(^ghy03-.*)

正規表現での検索と組み合わせる

SELECT *
FROM orders
WHERE order_code REGEXP (

  SELECT CONCAT('(^', (
    SELECT GROUP_CONCAT(item_code SEPARATOR '-.*)|(^')
    FROM items
    WHERE type = 'パン';
  ), '-.*)')

);

こんな感じで検索できるようです。

32
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
24