コマンド道場

LIKE 述語(部分一致)の使い方

形に当てはまる行だけが残る

shain社員

namebusho_id
山本4
山田3
中村2
井上7

name LIKE '山%'形に当てはまった行

namebusho_id
山本4
山田3

WHERE name LIKE '山%'

  • 取り消し線= 条件に合わないので結果に出てこない行
  • 社員 18 行 → 形に当てはまった行 216 行が消えます)

18 行のうち残るのは 2 行です。「山」で始まる名前だけが当てはまります。

LIKE は「この形に当てはまる文字列か」を調べる述語です。 使う記号は %(0 文字以上の任意)_(ちょうど 1 文字) の 2 つだけ。= は文字列を丸ごと比べるので、この 2 つは解釈されません。

未確認の製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database

未確認: IBM Db2

製品ごとの対応表(根拠つき)を見る

このページの実行結果と図は、すべて本物のデータベースに同じ SQL を流して得たものです。手で書いた「たぶんこうなる」ではありません。

01使う記号は % と _ の 2 つ

結論: % は 0 文字以上の任意の並び、_ はちょうど 1 文字です。

  • '山%' … 山で始まる(前方一致)
  • '%田%' … 田を含む(部分一致)
  • '%子' … 子で終わる(後方一致)
  • '_村' … 1 文字 + 村(2 文字ちょうど

% は 0 文字にも当てはまるので、'%田%' は「田」だけの名前にも当てはまります。

⚠️ 速さの話も 1 つだけ。 前方一致('山%')は索引で絞り込めることがありますが、先頭が % の形は索引をたどれません。大きな表で '%…%' を多用すると遅くなります。

1 行ずつ、何をしているか
  1. SELECT nameどの列を出すか
  2. FROM shainどの表を見るか
  3. WHERE name LIKE '山%'「山」で始まる行だけ残す
  4. ORDER BY shain_id並び順

LIKE は WHERE の中で使う述語です。返るのは true / false / unknown のいずれかで、真になった行だけが残ります。

山で始まる(前方一致)
SELECT name
FROM shain
WHERE name LIKE '山%'
ORDER BY shain_id;
name
山田
山本

2

田を含む(部分一致)
SELECT name
FROM shain
WHERE name LIKE '%田%'
ORDER BY shain_id;
name
田中
吉田
山田

3

3 行です。田中のように先頭にある場合も、吉田・山田のように後ろにある場合も当てはまります。

_ はちょうど 1 文字
SELECT name
FROM shain
WHERE name LIKE '_村'
ORDER BY shain_id;
name
中村
木村

2

2 行です。「村」で終わる 2 文字の名前だけが当てはまります。'%村' なら文字数を問いませんが、'_村' は 2 文字ちょうどです。

02= はワイルドカードを解釈しない

結論: =% を書いても、記号としてではなく「% という文字」として比べられます。

WHERE name = '山%' は「名前がちょうど『山%』という 2 文字の人」を探します。そんな人はいないので 0 行です。

エラーにならないので、LIKE と書くつもりで = と書いてしまうと、「該当なし」という正しそうな答えが返ってきます。

逆に、ワイルドカードを使わない LIKE 'aaa'= 'aaa' と同じ意味です。形で探すなら LIKE、丸ごと一致なら = と使い分けてください。

= だと 0 行(エラーにはならない)
SELECT name
FROM shain
WHERE name = '山%';
name

0

「山%」という名前の人はいないので 0 行です。LIKE と書き間違えたことに気づけません。

03⚠️ よくある間違い:大文字小文字を区別するかは環境で変わる

結論: LIKE が大文字小文字を区別するかは、製品と照合順序(collation)で変わります。

このサイトの実行環境では区別します'ABC' LIKE 'abc' は false です。一方、MySQL の既定の照合順序では区別しない(true になる)ことが多く、同じ SQL が環境によって違う結果を返します

確実に区別せずに探したいなら、両側を LOWER() で揃えるのがどの製品でも通る書き方です。

  • WHERE LOWER(name) LIKE LOWER('%abc%')

⚠️ PostgreSQL には ILIKE という大文字小文字を区別しない述語がありますが、これは PostgreSQL 固有で他製品にはありません。移植する予定があるなら LOWER() を使ってください。

この環境では大文字小文字を区別する
SELECT 'ABC' LIKE 'abc' AS chigau_ookisa,
       'ABC' LIKE 'ABC' AS onaji_ookisa;
chigau_ookisaonaji_ookisa
falsetrue

1

左が false、右が true です。MySQL の既定設定では左も true になることが多く、ここが環境差になります。

04⚠️ よくある間違い:% や _ 自体を探すときはエスケープする

結論: %_ を「記号ではなく文字として」探したいときは、直前に \ を付けます。

_ は「任意の 1 文字」なので、'a_b' というパターンは axb にも当てはまってしまいます。アンダースコアそのものを探したいなら 'a\_b' と書きます。

商品コードやファイル名のように _% を含むデータでは、これを忘れると余計な行まで拾います。エラーにならないので、件数が多いことに気づかないと見逃します。

⚠️ 使うエスケープ文字は ESCAPE 句で変えられます(例: LIKE 'a$_b' ESCAPE '$')。既定が \ かどうかは製品差があるので、確実にしたいときは ESCAPE を明示してください。

エスケープの有無で拾う行が変わる
SELECT 'axb' LIKE 'a_b'   AS wildcard,
       'axb' LIKE 'a\_b'  AS escape_shita,
       'a_b' LIKE 'a\_b'  AS honmono;
wildcardescape_shitahonmono
truefalsetrue

1

左は true(_ が任意の 1 文字として働き axb に当たる)、中央は false(アンダースコアそのものを探すので axb は当たらない)、右は true です。

05⚠️ よくある間違い:NULL には当てはまらない

結論: 列が NULL の行は、どんなパターンにも当てはまりません。 NOT LIKE でも出てきません。

NULL LIKE '%' は false ではなく unknown です。'%' は「何でもよい」という意味ですが、値が分からないものは「何でもよい」にも当てはまらない、と考えると腑に落ちます。

比較演算子や IN とまったく同じ規則です。「〜を含まない行」を NOT LIKE で出したのに件数が足りないときは、その列に NULL があるか確かめてください。NULL も含めたいなら OR 列 IS NULL を足します。

「何でもよい」にも当てはまらない
SELECT NULL LIKE '%' AS nandemo_yoi_hazu;
nandemo_yoi_hazu
NULL

1

true ではなく NULL(unknown)が返ります。WHERE に書けばその行は残りません。

NOT LIKE で「〜で終わらない」
SELECT busho_name
FROM busho
WHERE busho_name NOT LIKE '%業'
ORDER BY busho_id;
busho_name
経営
開発
管理
基盤
法務
マーケ

6

6 行です。この表の busho_name は NULL を許さない列なので全件が判定され、「業」で終わる営業だけが除かれています。

自分で打ってみる

このページの例と同じデータが入った本物のデータベースを、この場(あなたのブラウザの中)で起動できます。打った SQL がサーバーへ送られることはありません。

押すと初回だけ約 9MB を読み込みます(2 回目以降はキャッシュされます)。

解いてみる

読んだだけでは書けるようになりません。実行結果で採点します。

ここで出てくる関数を引く

関連するトピック

  • 比較演算子丸ごと一致で比べるときはこちらです。
  • IN 述語候補が決まっているなら LIKE より IN が向いています。
  • 文字列関数LOWER などで揃えてから比べる方法です。
  • WHERE 句LIKE をいちばん使う場所です。

根拠(一次情報)