こんにちは!kossyです!
今回はPostgreSQLにおけるLIKEとILIKEの違いをRails上で検証してみましたので、ブログに残してみたいと思います。
環境
PostgreSQL 12.5系
Rails 6.0.3
検証
まずはドキュメントを読んでみます。
9.7.1. LIKE
LIKE式は供給されたpatternにstringが一致すれば真を返します。 (想像される通り、NOT LIKE式はLIKE式が真を返す場合には偽を返し、その逆もまた同じです。 同等の式としてNOT (string LIKE pattern)とも表現できます。)
patternがパーセント記号もしくはアンダースコアを含んでいない場合patternは自身の文字列そのものです。この場合LIKE式は等号演算子のように振舞います。 patternの中にあるアンダースコア(_)は任意の一文字との一致を意味し、パーセント記号(%)は0文字以上の並びとの一致を意味します。
出典: https://www.postgresql.jp/document/12/html/functions-matching.html
ドキュメントに記載はありませんが、LIKEは大文字小文字を区別して検索を行います。
以下のようなレコードがあるとします。
id: 1, first_name: "Kota", last_name: "Omura", first_name_kana: "コウタ", last_name_kana: "オムラ",
このレコードをLIKE句を使って取得します。
Employee.where('first_name LIKE ?', '%Kota%') => Employee Load (3.4ms) SELECT "employees".* FROM "employees" WHERE (first_name LIKE '%Kota%') [#<Employee:0x000055b9718b3460 id: 1, first_name: "Kota", last_name: "Omura", first_name_kana: "コウタ", last_name_kana: "オムラ">]
Kotaと検索することで取得できました。ではここで先頭のKを小文字にして検索してみます。
Employee.where('first_name LIKE ?', '%kota%') => Employee Load (6.5ms) SELECT "employees".* FROM "employees" WHERE (first_name LIKE '%kota%') []
取得できませんでした。LIKEは大文字小文字を区別して検索していることがわかりますね。
次にILIKEを使って、先頭のKは小文字のまま検索してみます。
Employee.where('first_name ILIKE ?', '%kota%') => Employee Load (6.9ms) SELECT "employees".* FROM "employees" WHERE (first_name ILIKE '%kota%') [#<Employee:0x000055b971bf6488 id: 1, first_name: "Kota", last_name: "Omura", first_name_kana: "コウタ", last_name_kana: "オムラ">]
ILIKEを使えば先頭のKが小文字でもレコードを取得することができました。
試しに「KOTA」で検索もしてみましょう。
Employee.where('first_name ILIKE ?', '%KOTA%') => Employee Load (6.5ms) SELECT "employees".* FROM "employees" WHERE (first_name ILIKE '%KOTA%') [#<Employee:0x000055b971ddd328 id: 1, first_name: "Kota", last_name: "Omura", first_name_kana: "コウタ", last_name_kana: "オムラ">]
取得できました。ILIKEは大文字小文字を区別せずに検索を行う挙動のようですね。
ドキュメントを読むと、ILIKE句はSQL標準機能ではなく、PostgreSQLの拡張機能のようです。
現在のロケールに従って大文字小文字を区別しない一致を行うのであれば、LIKEの代わりにILIKEキーワードを使うことができます。
これは標準SQLではなく、PostgreSQLの拡張です。出典:
https://www.postgresql.jp/document/12/html/functions-matching.html
ちなみにMySQLのLIKE句ではデフォルトで大文字小文字を区別しない(= PostgreSQLのILIKEと同じ挙動)ようです。
まとめ
大文字小文字を区別して検索を行いたい場合はLIKE句を、区別したくない場合はILIKE句を使って検索を行うようにしましょう。