MySQL の LIKE とワイルドカードでパターン検索する
WHERE 句で完全一致の条件を書くだけでは、実務の検索要件に対応しきれない場面が多くあります。「名前に"田"が含まれるユーザーを探したい」「メールアドレスが gmail.com で終わる行だけ取得したい」といった部分一致の検索には、LIKE 演算子とワイルドカードを組み合わせます。
LIKE の基本構文
LIKE は WHERE 句の中で使い、文字列のパターンを指定して一致する行を抽出します。
SELECT * FROM users
WHERE name LIKE '田%';このクエリは name が「田」で始まるすべての行を返します。ここで使っている % がワイルドカードです。MySQL の LIKE で使えるワイルドカードは 2 種類あります。
0 文字以上の任意の文字列に一致する。最もよく使うワイルドカード。
ちょうど 1 文字の任意の文字に一致する。文字数が決まっている場合に使う。
% は「何文字でもいい(0 文字でもいい)」という意味なので、'田%' は「田」「田中」「田村太郎」のすべてに一致します。一方、'田_' は「田中」「田辺」のように「田」+ちょうど 1 文字のパターンだけに一致し、「田」単体や「田村太郎」には一致しません。
ワイルドカードの位置による検索パターン
ワイルドカードをどこに置くかで、検索の意味が変わります。
'東京%' のようにワイルドカードを末尾に置く。「東京」で始まる値を検索する。インデックスが効きやすく、最も高速なパターン。
'%株式会社' のようにワイルドカードを先頭に置く。「株式会社」で終わる値を検索する。インデックスが効かないため、大量データでは遅くなりやすい。
'%山%' のように前後をワイルドカードで囲む。「山」を含む値を検索する。後方一致と同様にインデックスが効かない。
実際のクエリで確認してみましょう。商品テーブルから名前に「チョコ」を含む商品を探す場合は、次のように書きます。
SELECT product_name, price
FROM products
WHERE product_name LIKE '%チョコ%';これで「チョコレートケーキ」「ホワイトチョコ」「チョコ」のいずれも取得できます。
アンダースコアで文字数を限定する
_ は 1 文字ぶんのワイルドカードとして機能します。たとえば、3 文字の都市コードだけを取り出したい場合に使えます。
SELECT * FROM cities
WHERE code LIKE '___';アンダースコアを 3 つ並べることで、ちょうど 3 文字のコードだけに一致させています。% と _ は組み合わせることも可能です。
SELECT * FROM users
WHERE email LIKE '_____@gmail.com';このクエリは、@ の前がちょうど 5 文字で gmail.com のドメインを持つメールアドレスに一致します。
NOT LIKE で除外する
LIKE の否定形として NOT LIKE を使えば、パターンに一致しない行を取得できます。
SELECT * FROM users
WHERE email NOT LIKE '%@test.com';テスト用のメールアドレスを除外したいときなどに便利です。WHERE 句で複数の LIKE 条件を組み合わせることもできます。
SELECT * FROM products
WHERE product_name LIKE '%チョコ%'
OR product_name LIKE '%バニラ%';OR で繋げば「チョコ」か「バニラ」のどちらかを含む商品を取得できます。ただし、条件が増えると可読性が下がるので、その場合は後のロールで扱う REGEXP(正規表現)のほうが適しているかもしれません。
エスケープ処理
検索したい文字列にワイルドカード文字そのもの(% や _)が含まれている場合、そのまま書くとワイルドカードとして解釈されてしまいます。これを回避するにはエスケープ文字を使います。
SELECT * FROM products
WHERE discount_label LIKE '%30\%%';\% と書くことで、% をワイルドカードではなくリテラルの文字として扱います。このクエリは「30%」という文字列を含む行を取得します。
MySQL のデフォルトのエスケープ文字はバックスラッシュ \ ですが、ESCAPE 句を使って任意の文字に変更することもできます。たとえば LIKE '%30!%%' ESCAPE '!' と書けば ! がエスケープ文字として機能します。
直後のワイルドカードを通常の文字として扱わせる特殊文字のこと。
LIKE とパフォーマンス
LIKE は手軽に使える反面、書き方によってはクエリの速度に大きく影響します。
前方一致(‘abc%’)
インデックスを利用できる
高速に検索可能
前方一致の場合、B-Tree インデックスの構造をそのまま活用して効率的に絞り込めます。一方、'%abc' や '%abc%' のようにワイルドカードが先頭にあると、インデックスを使えずフルテーブルスキャンが発生します。
WHERE name LIKE ‘田中%’ のように先頭が確定している場合。インデックスの範囲スキャンで高速に処理される。
WHERE name LIKE ‘%太郎’ のように先頭が不定の場合。全行を走査する必要があるため、テーブルが大きいほど遅くなる。
大量のレコードに対して部分一致検索を頻繁に行う必要がある場合は、MySQL の FULLTEXT インデックスや外部の全文検索エンジンの導入を検討しましょう。LIKE による部分一致はあくまで手軽さが強みであり、大規模データでの高速検索には向かない手法です。
BINARY を使った大文字・小文字の区別
MySQL のデフォルトの照合順序(utf8mb4_general_ci など)では、LIKE の比較は大文字と小文字を区別しません。つまり LIKE '%apple%' は「Apple」「APPLE」「apple」のすべてに一致します。
SELECT * FROM products
WHERE product_name LIKE BINARY '%Apple%';BINARY キーワードを付けると、バイト単位の比較になり大文字・小文字が区別されます。ただし、BINARY を使うとインデックスが効かなくなる場合があるため、大規模なテーブルでは注意が必要です。照合順序をテーブルやカラム単位で設定するほうが、長期的には適切な対処法といえるでしょう。













