LIKE и ILIKE в SQL: поиск по шаблону с примерами

SQL Автор: Среда и версия: PostgreSQL 17.9, локаль en_US.utf8; примеры выполнены в отдельной учебной базе; проверено 7 сентября 2026
содержание

LIKE в SQL проверяет, соответствует ли строка шаблону. Символ % заменяет любую последовательность символов, включая пустую, а _ — ровно один символ. Для поиска в PostgreSQL без учёта регистра используют ILIKE. Например, name ILIKE '%sql%' найдёт названия SQL guide, sql workbook и PostgreSQL handbook.

Дальше все запросы выполняются в PostgreSQL 17.9. ILIKE — расширение PostgreSQL, поэтому переносить его в другую СУБД без проверки нельзя. Правила сопоставления регистра зависят от локали; примеры с ASCII-названиями позволяют проверить механику без особенностей конкретного алфавита. Определения операторов приведены в документации PostgreSQL.

Подготовить таблицу товаров

Выполни этот блок в учебном SQL-сеансе. Временная таблица существует только до его закрытия:

CREATE TEMP TABLE products (
    id integer PRIMARY KEY,
    name text
);

INSERT INTO products (id, name) VALUES
    (1, 'SQL guide'),
    (2, 'sql workbook'),
    (3, 'PostgreSQL handbook'),
    (4, 'T-shirt 100% cotton'),
    (5, 'usb_c cable'),
    (6, 'usb-c cable'),
    (7, 'USB hub'),
    (8, NULL),
    (9, 'SQL');

Здесь есть разные регистры, буквальные % и _, а также неизвестное название NULL.

SQL / 01

Знак % допускает и суффикс, и его отсутствие

Результат LIKE SQL% для четырёх значенийШаг 1: берём название товара. Шаг 2: проверяем LIKE 'SQL%'. Шаг 3: SQL guide и SQL дают true, sql workbook даёт false, NULL даёт неизвестный результат NULL. WHERE оставляет только true.01 / название02 / проверка03 / результатSQL guideLIKE 'SQL%'trueSQLLIKE 'SQL%'truesql workbookLIKE 'SQL%'falseNULLLIKE 'SQL%'NULL
LIKE 'SQL%' пропустит строки 1 и 9. Для строки с NULL результат неизвестен, поэтому она в выборку не попадёт.

SQL LIKE: начало, конец и часть строки

Выберем товары, названия которых начинаются с SQL:

SELECT id, name
FROM products
WHERE name LIKE 'SQL%'
ORDER BY id;

Результат:

idname
1SQL guide
9SQL

Товар SQL тоже подходит: % разрешает ноль символов. Без маски шаблон LIKE 'SQL' на нашей таблице совпадёт только с названием SQL; для обычного равенства понятнее написать name = 'SQL'.

Положение % меняет условие. Каждый шаблон из таблицы можно подставить в тот же запрос:

УсловиеЗадачаПодходящие id
name LIKE 'SQL%'Начинается с SQL1, 9
name LIKE '%cotton'Заканчивается на cotton4
name LIKE '%SQL%'Содержит SQL в любой позиции1, 3, 9
name LIKE 'SQL'Целиком совпадает с SQL9

LIKE сопоставляет всю строку. Без % по краям он не ищет фрагмент автоматически. Звёздочка * здесь тоже не заменяет %: это обычный символ, а не маска SQL LIKE.

Символ _ заменяет ровно один символ

Такой запрос найдёт два кабеля:

SELECT id, name
FROM products
WHERE name LIKE 'usb_c cable'
ORDER BY id;
idname
5usb_c cable
6usb-c cable

В шаблоне _ стоит между usb и c. На его месте разрешён один символ: и подчёркивание, и дефис подходят. Поэтому это условие не проверяет буквальное имя кабеля.

Разницу между пустой последовательностью и одним символом видно в короткой проверке:

SELECT
    '' LIKE '%' AS empty_matches_percent,
    '' LIKE '_' AS empty_matches_underscore;

Ответ — true и false. Число _ задаёт точную длину участка; % такой длины не задаёт.

ILIKE: поиск без учёта регистра в PostgreSQL

Заменим оператор, оставив тот же префикс:

SELECT id, name
FROM products
WHERE name ILIKE 'sql%'
ORDER BY id;
idname
1SQL guide
2sql workbook
9SQL

PostgreSQL handbook не попал в ответ: слово начинается с Postgre, а шаблон требует sql в начале. Для поиска в любой позиции используй ILIKE '%sql%' — на наших данных это строки 1, 2, 3 и 9.

Для нелатинских названий проверяй поведение на локали своей базы. ILIKE не означает поиск похожих слов: он не исправляет опечатки и не делает транслитерацию.

ESCAPE: как найти буквальные % и _

Для поиска знака процента выберем ! как escape-символ. Он отменяет специальный смысл следующего % или _:

SELECT id, name
FROM products
WHERE name LIKE '%!%%' ESCAPE '!'
ORDER BY id;

Вернётся строка 4, T-shirt 100% cotton. Шаблон читается как три части: % допускает начало, !% требует настоящий знак процента, последний % допускает конец.

Буквальное подчёркивание ищется аналогично:

SELECT id, name
FROM products
WHERE name LIKE '%!_%' ESCAPE '!'
ORDER BY id;

Теперь подходит только строка 5, usb_c cable. Сам escape-символ тоже нужно экранировать: !! означает один !.

SELECT 'wow!' LIKE '%!!' ESCAPE '!' AS ends_with_exclamation;

Результат — true. Явный ESCAPE '!' помогает не путать экранирование шаблона с обратными слешами в строках SQL и языка приложения.

NOT LIKE и NULL: почему пропал товар без названия

Запрос «всё, что не начинается с SQL»:

SELECT id, name
FROM products
WHERE name NOT LIKE 'SQL%'
ORDER BY id;

Он вернёт id 2, 3, 4, 5, 6 и 7. Строки 8 нет: сравнение неизвестного названия с шаблоном даёт NULL, а отрицание неизвестности не превращает её в true.

Если товары без названия тоже должны входить в результат, назови это условие явно:

SELECT id, name
FROM products
WHERE name NOT ILIKE '%sql%' OR name IS NULL
ORDER BY id;

Ответ содержит id 4, 5, 6, 7 и 8. Обработка отсутствующих значений и оператор IS NULL описаны в документации PostgreSQL. Более подробно трёхзначная логика разобрана в статье про NULL.

Как передать поисковую строку из приложения

Не вставляй пользовательский ввод внутрь SQL через конкатенацию. Передавай целый шаблон параметром. Механизм можно проверить прямо в PostgreSQL:

PREPARE find_products(text) AS
SELECT id, name
FROM products
WHERE name ILIKE $1 ESCAPE '!'
ORDER BY id;

EXECUTE find_products('%sql%');
EXECUTE find_products('%!_%');
DEALLOCATE find_products;

Первое выполнение вернёт id 1, 2, 3 и 9, второе — id 5. $1 обозначает значение параметра, а не часть текста запроса. В драйвере приложения синтаксис заполнителя может быть другим; механизм PREPARE описан в справочнике PostgreSQL.

Параметризация защищает структуру SQL, но не отключает маски. Если пользователь ввёл %, параметр со значением %%% всё ещё найдёт любое известное название. Для буквального поиска сначала замени в пользовательском тексте ! на !!, затем % на !%, _ на !_ и только после этого добавь % с двух сторон. Для ввода usb_c получится %usb!_c%. Если интерфейс намеренно разрешает пользователю маски, такое экранирование, наоборот, меняет согласованное поведение поиска.

Почему индекс не всегда ускоряет LIKE

Для префикса LIKE 'SQL%' PostgreSQL может использовать B-tree; при локали, отличной от C, может понадобиться специальный класс операторов. У LIKE '%SQL%' нет фиксированного начала, поэтому такой поиск не получает то же преимущество обычного B-tree. Это ограничение описано в документации типов индексов.

По таблице из девяти товаров нельзя оценить ускорение: последовательное чтение здесь дёшево. Если поиск стал медленным на реальных данных, проверь план через EXPLAIN ANALYZE, затем выбирай индекс под фактическое условие. Варианты для текстового поиска разобраны в руководстве по индексам PostgreSQL.

Для самостоятельной проверки найди товары, названия которых содержат буквальное подчёркивание или знак процента. На этой таблице должны остаться только id 4 и 5; usb-c cable в ответ попадать не должен.

Источники