SQLで「指定したIDの中から、名前が特定の文字列で始まる行」を探すなら、INとLIKEをANDで組み合わせます。一方、「複数の前方一致パターンのどれか」を探すならLIKEをORでつなぎます。INにワイルドカードを並べてもパターン検索にはなりません。この記事では、両者の違いとPostgreSQLのLIKE ANYを、同じテーブルで比較します。
IN句とLIKE句の基本
IN句の基本
INは、指定した値のいずれかと等しい行を抽出します。例えばname IN ('田中%', '佐藤%')の%は普通の文字であり、「田中で始まる」という意味にはなりません。
SELECT * FROM users WHERE id IN (1, 2, 3);
LIKE句の基本
LIKEはパターンに一致する行を抽出します。%は0文字以上、_は任意の1文字です。田中%は「田中」で始まる名前、%田中%は途中を含め「田中」がある名前を探します。大文字・小文字などの比較はDBMSや照合順序に依存します。
SELECT * FROM users WHERE name LIKE '田中%';
IN句とLIKE句の組み合わせ
基本形:INとLIKEをANDで絞り込む
次はIDが1・2・3のいずれかで、かつ名前が「田中」で始まる行を探します。INとLIKEは別々の条件です。
SELECT id, name
FROM users
WHERE id IN (1, 2, 3)
AND name LIKE '田中%'
ORDER BY id;
実践例
テーブルの設定
まずは、実践例で使用するテーブルの設定を見ていきましょう。
| id | name |
|---|---|
| 1 | 田中太郎 |
| 2 | 佐藤次郎 |
| 3 | 鈴木三郎 |
具体的なクエリ例
複数の名前パターンを検索する場合は、LIKEをORでつなぎます。次の例では、指定IDの条件も残しています。ORの条件を括弧でまとめることが重要です。
SELECT id, name
FROM users
WHERE id IN (1, 2, 3)
AND (name LIKE '田中%' OR name LIKE '佐藤%')
ORDER BY id;
掲載テーブルでは、基本形はID 1の田中太郎、ORを使った例はID 1の田中太郎とID 2の佐藤次郎を返します。IDで絞る必要がなければINの条件を外し、括弧内のLIKE条件だけを使います。ANDはORより先に評価されるため、括弧を省略すると指定IDの外にある「佐藤」で始まる行も対象になり得ます。
これらのIN・LIKE・AND・ORはPostgreSQLやMySQL、SQL Serverなどで使えますが、文字型と文字コードは環境に合わせます。SQL Serverで日本語のUnicodeリテラルを使う場合はN'田中%'、N'佐藤%'とし、列の型・照合順序も確認してください。
PostgreSQLではLIKE ANYで複数パターンを指定できる
PostgreSQLでは、次のように配列とANYを使えます。これはIN句を使った構文ではなく、PostgreSQLの配列を使う拡張構文です。MySQLやSQL Serverへそのまま貼り付けず、上のOR形式などを使ってください。
SELECT id, name
FROM users
WHERE name LIKE ANY (ARRAY['田中%', '佐藤%'])
ORDER BY id;この例も掲載テーブルではID 1と2に一致します。特定のIDに限定していない点は、直前のIN付きクエリと異なります。仕様はPostgreSQL:INと配列ANY、LIKEによるパターン検索を参照してください。
注意点
NULLと入力値の扱い
nameがNULLなら通常のLIKE条件には一致しません。NULLも取得したい場合は、検索条件へ明示的にOR name IS NULLを加え、他の条件との括弧を確認します。PostgreSQLのANYでは空配列はfalse、NULL配列やNULL要素を含む比較はunknownになる場合があり、空の検索条件や未入力値の扱いを決めておきます。
ユーザー入力をSQL文字列へ直接連結せず、使用するドライバーのパラメーター機能へ渡してください。パラメーター化しても、値中の%や_がワイルドカードである意味は残ります。文字として検索したい場合は、そのDBMSのESCAPE規則に従って別途処理します。SQLの引用符対策とLIKEのワイルドカード対策は別です。参考:SQL ServerのLIKE、MySQLのLIKE。
性能について
ORからANYへ書き換えただけで速くなるとは限りません。先頭に%を付ける検索、対象行数、列の型・照合順序、索引などで計画が変わります。実際のDBMSの実行計画と代表データで確認し、見た目の短さだけで性能を判断しないでください。例としてPostgreSQLの索引とパターン検索の条件も確認できます。
まとめ
値の候補を絞るINと、パターンを調べるLIKEは役割が違います。両方の条件を満たすならAND、複数パターンのどれかならLIKEをORで結びます。PostgreSQLのLIKE ANYは便利な別構文ですが、他のDBMSに共通ではありません。括弧、NULL、文字コード、入力値の扱いを確認して使い分けましょう。


コメント