ITの教科書検索
入門読了 約10分

SQLのLIKEとは ― %と_の使い方

SQLのLIKEは、名前の一部が合う行を選ぶ条件です。%は0文字以上、_は1文字に一致します。前方一致・ESCAPE・大文字小文字の扱いと、インデックスが効く条件が分かります。

目次
  1. SQLのLIKEとは
  2. %と_の違い
  3. 前方一致・後方一致・部分一致
  4. パターンを当てて一致する行を確かめる
  5. NOT LIKEとESCAPE
  6. 大文字と小文字の区別
  7. =・IN・BETWEENとの使い分け
  8. 前方一致とインデックス
  9. 練習問題

SQLのLIKEとは、文字列の一部が合う行を選ぶ条件

SQLのLIKEは、WHERE句で文字列の一部が合う行を選ぶための述語(条件を表す語)です。パターンの中では、%が0文字以上の任意の文字列に、_がちょうど1文字に一致します。

SELECT文のWHERE句は、=を使うと値がぴったり同じ行しか選べません。LIKEを使うと、USBで始まる商品やケーブルを含む商品のように、名前の一部で行を選べます。

SELECT 商品名 FROM 商品
WHERE 商品名 LIKE 'USB%';   -- USBで始まる商品名

LIKEの右側に書く文字列を、パターンと呼びます。パターンの中の%と_は、どんな文字の代わりにもなる記号として働きます。

%と_の違いは、一致する文字の数

%は何文字にでも一致し、_はちょうど1文字だけに一致します。%は0文字でもよいので、%の位置に文字が無くても一致します。_はその位置に必ず1文字を求めるので、文字が足りなくても余っても一致しません。

LIKE 'ネット%'ネット%一致%=0文字ネット塾%一致%=1文字ネットワーク%一致%=3文字LIKE 'ネット_'ネット_不一致1文字足りないネット塾_一致_=1文字ネットワーク_余り不一致2文字余る
同じ3つの文字列に2つのパターンを当てた結果です。ネット%のパターンでは、%が0文字・1文字・3文字のどれにも一致するので、3つとも一致します。ネット_のパターンでは、_がちょうど1文字だけに一致するので、ネット塾だけが一致します。

LIKEは、パターンが文字列の全体に合うかを調べます。PostgreSQLの文書も、LIKEは常に文字列全体を対象にすると説明しています。そのため、ネット_はネットワークの先頭3文字に合っても、残りの2文字が余るので一致しません。

_が一致するのは、1バイトではなく1文字です。PostgreSQLの文字コードがUTF8のデータベースで確かめると、漢字の塾も1文字として_に一致しました。全角のUSBと半角のUSBは別の文字なので、互いに一致しません。

前方一致・後方一致・部分一致と、_で文字数を決める書き方

%をパターンのどこに置くかで、探し方が変わります。後ろに置けば前方一致、前に置けば後方一致、両側に置けば部分一致になります。_を並べると、その位置の文字数を決められます。

%と_の置き方と、次の節の商品の表で一致する名前
書き方パターンの例一致する商品名
前方一致'USB%'USBケーブル・USBメモリ・USB-Cハブ
後方一致'%ケーブル'USBケーブル・LANケーブル・HDMIケーブル
部分一致'%ケーブル%'上の3つと、ケーブルカバー
文字数を決める'___ケーブル'USBケーブル・LANケーブル

%も_も無いパターンは、文字列そのものを表します。PostgreSQLの文書は、この場合のLIKEは=と同じ働きをすると説明しています。LIKE 'マウス' は、商品名がちょうどマウスの行だけに一致します。

パターンを当てて、一致する行を確かめる

次の図では、8行の商品の表にLIKEのパターンを試せます。パターンを選ぶか入力すると、一致する行が光ります。ボタンで選べるパターンの結果は、PostgreSQLで実際に実行して確かめたものです。

LIKE のパターン
SELECT 商品名 FROM 商品
WHERE 商品名 LIKE 'USB%';
一致する行:USBケーブル・USBメモリ・USB-Cハブ(3行)
USBで始まる名前が一致します。後ろの%は、何文字にでも一致します。
商品の表
番号商品名一致
1USBケーブル一致
2USBメモリ一致
3LANケーブル-
4HDMIケーブル-
5ケーブルカバー-
6マウス-
7マウスパッド-
8USB-Cハブ一致

'マウス%' と 'マウス_' を比べると、%と_の違いが分かります。%は0文字にも一致するので、マウスも一致します。_は必ず1文字を求めるので、マウスもマウスパッドも一致しません。

NOT LIKEと、%や_そのものを探すESCAPE

NOT LIKEは、パターンに合わない行を選ぶ

NOT LIKEは、LIKEの結果を逆にした条件です。NOT LIKE '%ケーブル%' は、ケーブルを含まない商品名の行を選びます。前の節の表では、USBメモリ・マウス・マウスパッド・USB-Cハブの4行が残ります。

列の値がNULLの行は、LIKEでもNOT LIKEでも選ばれません。NULLにLIKEを使うと、結果が真でも偽でもないUNKNOWNになるためです。WHERE句はUNKNOWNの行を結果に残さないので、NULLの行も含めたいときはOR 列 IS NULLを足します。

ESCAPEで、%や_を記号ではなく文字として扱う

10%オフのように、%の文字そのものを探したい場面があります。LIKE '10%' と書くと、%が記号として働き、10で始まる名前が全部一致します。クーポンの表で確かめると、次のようになります。

-- クーポン名:10%オフ、100円オフ、10個セット
WHERE クーポン名 LIKE '10%';               -- 3行とも一致
WHERE クーポン名 LIKE '10!%%' ESCAPE '!';  -- 10%オフだけ

ESCAPEで決めた文字の直後にある%や_は、記号ではなく普通の文字として扱われます。この文字をエスケープ文字と呼びます。上の例では!がエスケープ文字なので、!%は%の文字に、最後の%は記号として残りの文字列に一致します。!そのものを探すときは、!!と2つ重ねます。

ESCAPEを書かないときの扱いは、規格と製品で違います。SQLの規格では、ESCAPEを省くとエスケープ文字はありません。PostgreSQLは、省いたときにバックスラッシュをエスケープ文字として扱います。MySQLも同じですが、NO_BACKSLASH_ESCAPESというSQLモードが有効なときはエスケープ文字がありません。どの製品でも同じ意味にしたいときは、ESCAPEを明示して書きます。

大文字と小文字を区別するかは、製品と照合順序で決まる

LIKEが大文字と小文字を区別するかどうかは、製品によって違います。PostgreSQLのLIKEは既定の照合順序では区別するので、LIKE 'usb%' はUSBケーブルに一致しません。MySQLは、比べる文字列の照合順序で決まります。

LIKEでの大文字と小文字の扱い
製品大文字と小文字区別しないで探す方法
PostgreSQL既定の照合順序では、LIKEは区別するLIKEの代わりにILIKEを使う
MySQL照合順序で決まる名前が_ciで終わる照合順序では、LIKEのままで区別しない

照合順序は、文字をどう比べて並べるかの決まりです。MySQLの文書は、照合順序の名前の_ciを大文字と小文字を区別しない印、_csを区別する印として説明しています。 _binは文字のコードの値で比べるので、大文字と小文字は別の文字になります。

MySQLの文書の例では、'abc' LIKE 'ABC' の結果は真です。PostgreSQLのILIKEは規格に無い独自の機能なので、ほかの製品ではそのまま使えないことがあります。

=・IN・BETWEENとLIKEの使い分け

値がぴったり分かっているなら、LIKEではなく=で比べます。候補の値がいくつか決まっているなら、INで並べます。LIKEを使うのは、値の一部だけが分かっているときです。

WHERE 商品名 = 'マウス'                    -- 完全一致
WHERE 商品名 IN ('マウス', 'マウスパッド')  -- 候補のどれかと一致
WHERE 価格 BETWEEN 1000 AND 2000           -- 1000以上2000以下
WHERE 商品名 LIKE 'マウス%'                -- マウスで始まる

BETWEENは、値が範囲に入るかを調べる述語です。LIKEは文字の並びを調べるので、数値の大小は比べられません。

INとBETWEENをORやANDの式に書き換えた形と、BETWEENの両端の扱いは、INとBETWEENの記事で説明しています。INとEXISTSで別の表の値と比べる書き方は、サブクエリの記事にあります。

利用者が入力した語をそのままSQL文に埋め込むと、SQLインジェクションの原因になります。仕組みと対策は、SQLインジェクションとXSSの記事で説明しています。

前方一致はインデックスを使え、%で始まるパターンは使えない

インデックスに使うB-treeは、値を順に並べて持っています。LIKE 'USB%' のような前方一致なら、USBで始まる値が並ぶ範囲だけを索引でたどれます。%で始まるパターンは、どこから探せばよいかが決まらないので、索引の範囲をしぼれません。

MySQLの文書は、LIKEの右側が%や_で始まらない固定の文字列なら、インデックスを使えると説明しています。PostgreSQLの文書も、前方一致ならB-treeを使えると説明しています。ただしPostgreSQLでは、データベースのロケールがC以外だと、text_pattern_opsなどを指定したインデックスが必要です。

PostgreSQLで2万行の表にインデックスを作り、DBMSが選ぶ処理の手順(実行計画)を確かめました。LIKE 'item123%' では、索引で item123 以上 item124 未満の範囲を探す計画になりました。LIKE '%123' と LIKE '%m123%' では、全ての行を順に読む計画になりました。

参考にした資料

練習問題(全5問)

Q1商品名 LIKE 'マウス_' に一致するのはどれ?
Q2商品名 LIKE '%ケーブル' に一致しないのはどれ?
Q3名前の中に % の文字そのものを含む行を探す条件はどれ?
Q4PostgreSQLの既定の照合順序で、商品名が USBケーブル の行に WHERE 商品名 LIKE 'usb%' を実行した。結果はどうなる?
Q5商品名にB-treeインデックスがあるとき、インデックスを使える場合があるのはどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

データベースの記事を続けて読む

データベース 全36本中9本目