LIKE в SQL — поиск по шаблону с примерами
Коротко
LIKE -- оператор SQL для поиска строк по шаблону. Нужен, когда точное значение неизвестно: найти всех пользователей с почтой на gmail.com, отфильтровать UTM-метки по кампании, выбрать города, начинающиеся на «Моск». На собеседовании по SQL LIKE встречается в задачах на фильтрацию и чистку данных -- вещь базовая, но ошибки в шаблонах допускают часто.
Синтаксис LIKE
SELECT *
FROM users
WHERE email LIKE '%@gmail.com'LIKE сравнивает строку с шаблоном. В шаблоне два спецсимвола:
| Символ | Значение | Пример | Совпадает с |
|---|---|---|---|
% |
Любое количество любых символов (включая ноль) | 'A%' |
'A', 'Anna', 'A123' |
_ |
Ровно один любой символ | 'A_' |
'Ab', 'A1', но не 'A' и не 'Abc' |
Шаблоны можно комбинировать:
-- имя из 4 букв, начинается на 'И'
WHERE name LIKE 'И___'
-- email содержит 'test' где угодно
WHERE email LIKE '%test%'
-- второй символ -- 'a'
WHERE name LIKE '_a%'NOT LIKE
Инвертирует условие -- все строки, которые не соответствуют шаблону:
SELECT *
FROM users
WHERE email NOT LIKE '%@internal.company.ru'Удобно для исключения тестовых данных, внутренних аккаунтов, служебных записей.
ILIKE -- регистронезависимый поиск (PostgreSQL)
Стандартный LIKE регистрозависим: 'Anna' LIKE 'anna%' вернёт FALSE. В PostgreSQL есть ILIKE -- работает так же, но игнорирует регистр:
SELECT *
FROM users
WHERE city ILIKE '%москва%'
-- найдёт 'Москва', 'москва', 'МОСКВА'В MySQL LIKE по умолчанию регистронезависим (зависит от collation таблицы). В SQL Server -- тоже (по умолчанию). В PostgreSQL используйте ILIKE или приведите к одному регистру через LOWER():
WHERE LOWER(city) LIKE '%москва%'ESCAPE -- если нужен литеральный % или _
Если в данных встречается символ % или _ и нужно искать именно его, укажите escape-символ:
-- найти строки, содержащие '20%'
WHERE description LIKE '%20\%%' ESCAPE '\'Здесь \% -- это литеральный символ процента, а не шаблон. Без ESCAPE невозможно отличить спецсимвол от обычного.
SIMILAR TO и регулярные выражения (PostgreSQL)
Для сложных шаблонов PostgreSQL предлагает две альтернативы:
SIMILAR TO -- гибрид LIKE и регулярных выражений:
-- email заканчивается на gmail.com или yandex.ru
WHERE email SIMILAR TO '%(gmail.com|yandex.ru)'Оператор ~ -- полноценные регулярные выражения POSIX:
-- телефон в формате +7XXXXXXXXXX
WHERE phone ~ '^\+7\d{10}$'
-- регистронезависимый вариант: ~*
WHERE name ~* '^(анна|anna)'Регулярные выражения мощнее, но медленнее LIKE. Используйте их, когда шаблонов % и _ не хватает.
Производительность
Главное правило: LIKE 'abc%' использует индекс, '%abc' -- нет.
Если шаблон начинается с фиксированной строки, БД может использовать B-tree индекс для быстрого поиска. Если шаблон начинается с % -- придётся сканировать всю таблицу.
-- быстро (index scan, если есть индекс на email)
WHERE email LIKE 'admin%'
-- медленно (full table scan)
WHERE email LIKE '%admin%'Для полнотекстового поиска по %текст% на больших таблицах используйте:
- GIN/GiST-индексы с
pg_trgmв PostgreSQL - FULLTEXT-индексы в MySQL
- Внешние движки поиска (Elasticsearch, Meilisearch)
ILIKE и LOWER() LIKE тоже не используют обычный B-tree индекс. В PostgreSQL для регистронезависимого поиска создайте индекс на LOWER(column) или используйте pg_trgm.
Практические примеры
Фильтрация email по домену:
SELECT user_id, email
FROM users
WHERE email LIKE '%@yandex.ru'Поиск пользователей по началу имени:
SELECT user_id, name
FROM users
WHERE name ILIKE 'алекс%'
-- Александр, Алексей, АлександраАнализ UTM-меток:
SELECT
utm_campaign,
COUNT(*) AS visits
FROM onboarding_runs
WHERE utm_source LIKE 'tg_%'
GROUP BY utm_campaign
ORDER BY visits DESCЧистка данных -- тестовые аккаунты:
DELETE FROM users
WHERE email LIKE '%+test%@%'
OR email LIKE '%@test.%'Типичные ошибки
Забыли % с нужной стороны. WHERE name LIKE 'Иван' -- это то же самое, что WHERE name = 'Иван'. Для поиска по подстроке нужен % с обеих сторон: LIKE '%Иван%'.
LIKE с числовыми столбцами. LIKE работает со строками. WHERE age LIKE '2%' может привести к неявному приведению типа или ошибке. Для чисел используйте диапазоны: WHERE age BETWEEN 20 AND 29.
Регистр. В PostgreSQL LIKE регистрозависим. 'Москва' LIKE '%москва%' вернёт FALSE. Используйте ILIKE или LOWER().
Шаблон % в начале на большой таблице. WHERE column LIKE '%value%' на таблице с миллионами строк без специального индекса -- это full scan. Если запрос тормозит, проверьте план через EXPLAIN.
Вопросы с собеседований
-- Чем отличается % от _ в LIKE?
-- % соответствует любому количеству символов (включая ноль), _ -- ровно одному символу. LIKE 'A%' найдёт 'A', 'Ab', 'Abc'. LIKE 'A_' найдёт только строки из двух символов, начинающиеся на A.
-- Как сделать регистронезависимый поиск по шаблону в PostgreSQL?
-- Использовать ILIKE вместо LIKE, либо привести обе стороны к одному регистру: WHERE LOWER(name) LIKE LOWER('%anna%'). ILIKE -- идиоматический вариант для PostgreSQL.
-- Будет ли использоваться индекс для WHERE email LIKE '%gmail.com'?
-- Нет. Шаблон начинается с %, поэтому B-tree индекс не поможет -- БД выполнит full table scan. Индекс используется только когда шаблон начинается с фиксированной строки: LIKE 'admin%'.
-- Как найти строки, содержащие символ % в данных?
-- Использовать ESCAPE: WHERE column LIKE '%100\%%' ESCAPE '\'. Здесь \% -- литеральный символ процента.
-- Напишите запрос: найти всех пользователей, чьё имя начинается на 'А' и содержит ровно 5 букв.
-- SELECT * FROM users WHERE name LIKE 'А____'. Один символ А и четыре подчёркивания _ -- итого 5 символов.
Потренируйтесь решать задачи — откройте тренажёр с 1500+ вопросами для подготовки к собеседованиям аналитиков.
FAQ
Чем LIKE отличается от =?
= проверяет точное совпадение. LIKE позволяет использовать шаблоны % и _. WHERE name = 'Иван' найдёт только 'Иван', а WHERE name LIKE 'Иван%' -- также 'Иванов', 'Иванова' и т.д. Если шаблон не содержит спецсимволов, LIKE работает как =, но чуть медленнее.
Работает ли LIKE с NULL?
Нет. Любое сравнение с NULL даёт NULL, не TRUE и не FALSE. WHERE name LIKE '%test%' не вернёт строки, где name равен NULL. Если нужно обработать NULL -- добавьте отдельное условие: WHERE name LIKE '%test%' OR name IS NULL.
Когда использовать LIKE, а когда -- регулярные выражения?
LIKE достаточен для простых шаблонов: начинается с, заканчивается на, содержит подстроку. Для сложных паттернов (альтернативы, классы символов, повторения) используйте ~ в PostgreSQL или REGEXP в MySQL. LIKE быстрее и проще в чтении -- начинайте с него.
Поддерживается ли ILIKE во всех СУБД?
Нет. ILIKE -- расширение PostgreSQL. В MySQL LIKE по умолчанию регистронезависим. В SQL Server поведение зависит от collation. В стандартном SQL регистронезависимый поиск делается через LOWER(): WHERE LOWER(column) LIKE LOWER('%pattern%').
Как тренироваться
LIKE -- один из первых операторов, которые спрашивают на собеседовании по SQL. В тренажёре Карьерник есть задачи на фильтрацию строк по шаблону, работу с % и _, и регистронезависимый поиск. Также полезно разобрать CASE WHEN -- часто используется вместе с LIKE для условной логики.
Больше вопросов по SQL -- в примерах вопросов по всем темам.