POSITION(), STRPOS() и INSTR() в SQL — поиск позиции подстроки в строке

Функция возвращает номер позиции, с которой начинается первое вхождение подстроки (нумерация с 1), или 0, если подстрока не найдена. Аналитику она нужна, чтобы находить разделители и парсить строки: где стоит '@' в email, где начинается query-параметр в URL. Синтаксис зависит от диалекта: в PostgreSQL это POSITION(sub IN str) или STRPOS(str, sub), в SQLite и MySQL — INSTR(str, sub). Встроенного INSTR в PostgreSQL нет.

Синтаксис

POSITION(подстрока IN строка) -- стандарт / PostgreSQL STRPOS(строка, подстрока) -- PostgreSQL INSTR(строка, подстрока) -- SQLite / MySQL

Примеры использования

Пример 1: Позиция символа @ в email

SELECT email,
       POSITION('@' IN email) AS at_pos
FROM users
LIMIT 3;

Результат:

email           | at_pos
anna@yandex.ru  | 5
ivan@ozon.ru    | 5
maria.k@vk.com  | 8

Пример 2: STRPOS: где начинается query-строка в URL

SELECT url,
       STRPOS(url, '?') AS q_pos
FROM events
LIMIT 3;

Результат:

url             | q_pos
/catalog?page=2 | 9
/order          | 0
/search?q=sql   | 8

Пример 3: Фильтр строк, где есть подстрока

SELECT id, utm_source
FROM orders
WHERE POSITION('promo' IN utm_source) > 0;

Результат:

id | utm_source
17 | promo_summer
42 | promo_vk
Порешать SQL-задачи в тренажёре →

Типичная ошибка

Нумерация начинается с 1, а при отсутствии подстроки возвращается 0 (не NULL) — учитывайте это в условиях WHERE. Если любой из аргументов NULL, результат тоже NULL. Поиск чувствителен к регистру, поэтому часто оборачивают в LOWER().

Где спрашивают на собеседовании

Спрашивают в задачах на парсинг строк — почти всегда в паре с SUBSTRING/SUBSTR, чтобы вырезать домен из email или сегмент из пути.

FAQ: частые вопросы про POSITION

Чем POSITION отличается от STRPOS?

Результат одинаковый — оба возвращают позицию первого вхождения. Разница только в синтаксисе: POSITION(sub IN str) — стандартный ANSI-вариант, а STRPOS(str, sub) — функция PostgreSQL с обычным порядком аргументов (сначала строка, потом подстрока).

Работает ли INSTR в PostgreSQL?

Нет, встроенного INSTR в PostgreSQL нет — используйте POSITION или STRPOS. INSTR доступен в SQLite и MySQL. Если переносите запрос из SQLite в PostgreSQL, замените INSTR(str, sub) на STRPOS(str, sub).

Что возвращает функция, если подстрока не найдена?

Возвращает 0, а не NULL. Поэтому проверка наличия подстроки пишется как POSITION('x' IN col) > 0. Нумерация позиций одинаковая во всех диалектах — с единицы, а не с нуля.

Задачи в тренажёре по теме

Смежные темы SQL

Строковые функции · null-handling

Другие функции SQL

COALESCE · NULLIF · COUNT · SUBSTR · CAST · CONCAT

Открыть SQL-тренажёр (565 задач) →