web-dev-qa-db-ja.com

MySQLとPostgresの両方で大文字と小文字を区別しないクエリをどのように記述しますか?

開発用にローカルでMySQLデータベースを実行していますが、Postgresを使用するHerokuにデプロイしています。 Herokuはほとんどすべてを処理しますが、大文字と小文字を区別しないLikeステートメントは大文字と小文字を区別します。 iLikeステートメントを使用できますが、ローカルのMySQLデータベースはそれを処理できません。

MySQLとPostgresの両方と互換性がある、大文字と小文字を区別しないクエリを記述する最良の方法は何ですか?または、アプリが通信しているデータベースに応じて、LikeステートメントとiLikeステートメントを別々に記述する必要がありますか?

64
DA.
select * from foo where upper(bar) = upper(?);

呼び出し元でパラメーターを大文字に設定すると、2番目の関数呼び出しを回避できます。

58
Paul Tomblin

この話の教訓は、開発と生産に異なるソフトウェアスタックを使用しないことです。決して。

あなたは、devで再現できないバグになってしまいます。あなたのテストは価値がないでしょう。しないでください。

別のデータベースエンジンを使用することは問題外です-LIKE以外の動作をするケースがはるかに多くあります(また、データベースで使用されている照合を確認しましたか?あらゆるケースで同じですか?同じ働きをするvarchar列のORDER BYを忘れる)

73
MarkR

Arelを使用:

Author.where(Author.arel_table[:name].matches("%foo%"))

matchesはPostgresにILIKE演算子を使用し、その他すべてにLIKE演算子を使用します。

36
jswanner

Postgresでは、これを行うことができます。

SELECT whatever FROM mytable WHERE something ILIKE 'match this';

MySQLに同等のものがあるかどうかはわかりませんが、これはいつでもできますが、少しwhichいですが、MySQLとpostgresの両方で動作するはずです。

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');
13
Adam Pierce

いくつかの答えがありますが、どれも非常に満足のいくものではありません。

  • LOWER(bar)= LOWER(?)はMySQLおよびPostgresでworkになりますが、 MySQLでひどく実行する:MySQLはLOWER関数のためにインデックスを使用しません。 Postgresでは、機能インデックス(LOWER(bar))を追加できますが、MySQLはこれをサポートしていません。
  • MySQLは(大文字と小文字を区別する collat​​ion を設定していない限り)大文字と小文字を区別しないマッチングを自動的に行い、そのインデックスを使用します。 (bar =?)。
  • データベース外のコードから、barおよびbar_lowerフィールドを維持します。ここで、 bar_lowerには、lower(bar)の結果が含まれます。 (これは、データベーストリガーを使用しても可能です)。 (このソリューションの説明は Drupal をご覧ください)。これは不器用ですが、少なくともほとんどすべてのデータベースで同じ方法で実行されます。
8
tims

REGEXPは大文字と小文字を区別せず(BINARYと併用しない限り)、次のように使用できます。

    SELECT id FROM person WHERE name REGEXP 'john';

...「John」、「JOHN」、「john」などに一致する.

5
Ben Wilhelm
2
RuelB

PostgreSQL 8.4を使用している場合は、 citext モジュールを使用して、大文字と小文字を区別しないテキストフィールドを作成できます。

2
MkV

ブロック内のサブストリングを一致させたい場合は、postgresで〜*を使用することもできます。 〜は大文字と小文字を区別する部分文字列、〜*は大文字と小文字を区別しない部分文字列に一致します。操作は遅いですが、検索に役立つと思うかもしれません。

Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';

両方が「ここに不均一なテキスト」にヒットします前者のみが「ここに不均一なテキスト」にヒットします

1
Sheldon Ross

searchlogic プラグインをチェックアウトすることを検討することもできます。このプラグインは LIKE/ILIKE の切り替えを行います。

1
Trevor Turk

上位への変換は、最もよく使用される3つのRailsデータベースバックエンド。PostgreSQL、MySQL、およびSQLiteはすべてこの構文をサポートします。互換性のある構文をカバーします。アプリケーションまたは条件文字列で検索文字列を大文字にして、少し見栄えの悪いものにしますが、互換性を得ると価値があると思います。

MySQLとSQLite3の両方に、大文字と小文字を区別しないLIKE演算子があります。大文字と小文字を区別するLIKE演算子と、大文字と小文字を区別しない検索用のPostgreSQL固有の(マニュアルによる)ILIKE演算子は、PostgreSQLのみにあります。 Railsアプリケーションの条件でLIKEの内側にILIKEを指定できますが、アプリケーションはMySQLまたはSQLiteで動作しなくなることに注意してください。

3番目のオプションは、使用しているデータベースエンジンを確認し、それに応じて検索文字列を変更することです。これは、ActiveRecordの接続アダプターにハッキング/モンキーパッチを適用し、クエリ実行の前にPostgreSQLアダプターにクエリ文字列を変更して、「LIKE」を「ILIKE」に置き換えることにより、より適切に行うことができます。ただし、このソリューションは最も複雑であり、両方の用語を大文字にするなどの簡単な方法に照らして、これは努力する価値がないと思います(ただし、この方法で多くのブラウニーポイントを得ることができます)。

0
Roadmaster