PostgreSQL: как сделать запрос без учета регистра - PullRequest
265 голосов
/ 10 августа 2011

Есть ли способ писать запросы без учета регистра в PostgreSQL, например Я хочу, чтобы следующие 3 запроса возвращали один и тот же результат.

SELECT id FROM groups where name='administrator'

SELECT id FROM groups where name='ADMINISTRATOR'

SELECT id FROM groups where name='Administrator'

Ответы [ 7 ]

371 голосов
/ 10 августа 2011

Используйте функцию LOWER для преобразования строк в нижний регистр перед сравнением.

Попробуйте:

SELECT id 
  FROM groups
 WHERE LOWER(name)=LOWER('Administrator')
170 голосов
/ 20 октября 2013

с использованием ILIKE вместо LIKE

SELECT id FROM groups WHERE name ILIKE 'Administrator'
110 голосов
/ 10 августа 2011

Наиболее распространенным подходом является строчная или прописная строка поиска и данные. Но есть две проблемы с этим.

  1. Работает на английском, но не на всех языках. (Может даже не в большинство языков.) Не каждая строчная буква имеет соответствующий Прописная буква; не каждая заглавная буква имеет соответствующий строчная буква.
  2. Использование таких функций, как lower () и upper (), даст вам последовательный сканирования. Он не может использовать индексы. В моей тестовой системе использование lower () занимает примерно в 2000 раз дольше, чем запрос, который может использовать индекс. (Тестовые данные имеют чуть более 100 тыс. Строк.)

Существует как минимум три менее часто используемых решения, которые могут быть более эффективными.

  1. Используйте модуль citext , который в основном имитирует поведение нечувствительного к регистру типа данных. Загрузив этот модуль, вы можете создать регистр без учета регистра CREATE INDEX ON groups (name::citext);. (Но см. Ниже.)
  2. Используйте сортировку без учета регистра. Это устанавливается при инициализации база данных. Использование сортировки без учета регистра означает, что вы можете принять практически любой формат из кода клиента, и вы все равно вернетесь полезные результаты. (Это также означает, что вы не можете выполнять запросы с учетом регистра. Дух.)
  3. Создать функциональный индекс. Создайте строчный индекс, используя CREATE INDEX ON groups (LOWER(name));. Сделав это, вы можете воспользоваться индекса с запросами типа SELECT id FROM groups WHERE LOWER(name) = LOWER('ADMINISTRATOR'); или SELECT id FROM groups WHERE LOWER(name) = 'administrator'; Вы должны запомнить , чтобы использовать LOWER (), хотя.

Модуль citext не предоставляет тип данных без учета регистра. Вместо этого он ведет себя так, как если бы каждая строка была в нижнем регистре. То есть он ведет себя так, как если бы вы вызывали lower() для каждой строки, как в номере 3 выше. Преимущество заключается в том, что программистам не нужно запоминать строчные буквы. Но вам нужно прочитать разделы «Поведение сравнения строк» ​​и «Ограничения» в документах, прежде чем вы решите использовать citext.

91 голосов
/ 07 февраля 2013

Вы можете использовать ILIKE. т.е.

SELECT id FROM groups where name ILIKE 'administrator'
50 голосов
/ 23 сентября 2012

Вы также можете прочитать ключевое слово ILIKE. Иногда это может быть полезно, хотя и не соответствует стандарту SQL. Смотрите здесь для получения дополнительной информации: http://www.postgresql.org/docs/9.2/static/functions-matching.html

24 голосов
/ 19 августа 2014

Вы также можете использовать регулярные выражения POSIX, например,

SELECT id FROM groups where name ~* 'administrator'

SELECT 'asd' ~* 'AsD', возвращает t

4 голосов
/ 08 октября 2018

Использование ~* может значительно улучшить производительность благодаря функциональности INSTR.

SELECT id FROM groups WHERE name ~* 'adm'

возвращает строки с именем, которое содержит OR, равное 'adm'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...