How do you write a case insensitive query for both MySQL and Postgres?

后端 未结 11 1979
南方客
南方客 2020-11-29 23:39

I\'m running a MySQL database locally for development, but deploying to Heroku which uses Postgres. Heroku handles almost everything, but my case-insensitive Like statements

相关标签:
11条回答
  • 2020-11-30 00:05

    REGEXP is case insensitive (unless used with BINARY), and can be used, like so...

        SELECT id FROM person WHERE name REGEXP 'john';
    

    ...to match 'John', 'JOHN', 'john', etc.

    0 讨论(0)
  • 2020-11-30 00:16

    Use Arel:

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

    matches will use the ILIKE operator for Postgres, and LIKE for everything else.

    0 讨论(0)
  • 2020-11-30 00:16

    Converting to upper is best as it covers compatible syntax for the 3 most-used Rails database backends. PostgreSQL, MySQL and SQLite all support this syntax. It has the (minor) drawback that you have to uppercase your search string in your application or in your conditions string, making it a bit uglier, but I think the compatibility you gain makes it worthwile.

    Both MySQL and SQLite3 have a case-insensitive LIKE operator. Only PostgreSQL has a case-sensitive LIKE operator and a PostgreSQL-specific (per the manual) ILIKE operator for case-insensitive searches. You might specify ILIKE insead of LIKE in your conditions on the Rails application, but be aware that the application will cease to work under MySQL or SQLite.

    A third option might be to check which database engine you're using and modify the search string accordingly. This might be better done by hacking into / monkeypatching ActiveRecord's connection adapters and have the PostgreSQL adapter modify the query string to substitute "LIKE" for "ILIKE" prior to query execution. This solution is however the most convoluted and in light of easier ways like uppercasing both terms, I think this is not worh the effort (although you'd get plenty of brownie points for doing it this way).

    0 讨论(0)
  • 2020-11-30 00:17

    You can also use ~* in postgres if you want to match a substring within a block. ~ matches case-sensitive substring, ~* case insensitive substring. Its a slow operation, but might I find it useful for searches.

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

    Both would hit on "Some Uneven text here" Only the former would hit on "Some UNEVEN TEXT here"

    0 讨论(0)
  • 2020-11-30 00:24

    You might also consider checking out the searchlogic plugin, which does the LIKE/ILIKE switch for you.

    0 讨论(0)
提交回复
热议问题