Как найти записи, начинающиеся с определенной буквы в SQL
Что проверяют
Базовое владение фильтрацией строк и знание тонкостей, из-за которых простой запрос возвращает не то. Следом обычно спрашивают про регистр, про несколько букв сразу и про то, будет ли такой запрос быстрым на большой таблице.
Как отвечать
Основной ответ это LIKE с шаблоном, где % означает любую последовательность символов, а _ ровно один символ:
- базовый случай:
WHERE name LIKE 'А%'вернёт строки, начинающиеся с «А»; - регистр: в PostgreSQL
LIKEчувствителен к регистру, без учёта регистра ищут черезILIKEилиlower(name) LIKE 'а%'. В MySQL и SQL Server всё решает collation, и стандартные настройки там обычно уже регистронезависимые (_ci,CI); - несколько букв:
name LIKE 'А%' OR name LIKE 'Б%', в SQL Server диапазонLIKE '[А-В]%', в PostgreSQL регулярное выражениеname ~ '^[АБВ]'; - альтернатива без шаблона:
LEFT(name, 1) = 'А'. Работает, но функция над колонкой обычно не даёт использовать индекс; - пробелы и NULL: значение с ведущим пробелом в выборку не попадёт, поэтому на грязных данных добавляют
TRIM. Строки сNULLне вернутся ни при каком шаблоне.
Про скорость: шаблон с фиксированным началом ('А%') может использовать B-tree индекс, а шаблон с % в начале нет. В PostgreSQL есть оговорка: при локали базы, отличной от C, для LIKE нужен индекс с классом операторов text_pattern_ops, а для поиска по подстроке используют триграммный индекс из расширения pg_trgm.
Где спотыкаются
Пишут '%А%' и получают все строки, где буква встречается в любом месте, а не только в начале.
Не проверяют регистр. Запрос, который в MySQL находил и «анна», и «Анна», после переезда на PostgreSQL теряет часть строк.
Забывают, что _ в данных тоже подстановочный символ. Шаблон 'user_%' найдёт и user1, поэтому такие символы экранируют: \_ в PostgreSQL и MySQL, [_] или ESCAPE в SQL Server.