Строковые функции SQL: шпаргалка для собеседования
Зачем аналитику строковые функции
Чистка данных, парсинг URL, извлечение доменов из email, normalized join по имени — строковые функции нужны в каждом проекте. На собесе их спрашивают в блоке «очистка данных».
Базовые функции
| Функция | Что делает | Пример |
|---|---|---|
LOWER(s) |
К нижнему регистру | 'HELLO' → 'hello' |
UPPER(s) |
К верхнему регистру | 'hello' → 'HELLO' |
LENGTH(s) |
Длина строки | 'abc' → 3 |
TRIM(s) |
Убрать пробелы с краёв | ' abc ' → 'abc' |
LTRIM/RTRIM(s) |
Слева/справа | |
REVERSE(s) |
Перевернуть | 'abc' → 'cba' |
Извлечение подстроки
SUBSTRING / SUBSTR
-- PostgreSQL, ClickHouse
SELECT SUBSTRING('2026-04-15', 1, 4) AS year; -- '2026'
SELECT SUBSTRING('2026-04-15', 6, 2) AS month; -- '04'
-- SUBSTR (алиас)
SELECT SUBSTR('hello world', 7) AS s; -- 'world'Индексация с 1, не с 0 — частая ловушка у тех, кто привык к Python.
LEFT / RIGHT
SELECT LEFT('example.com', 7) AS l; -- 'example'
SELECT RIGHT('example.com', 3) AS r; -- 'com'SPLIT_PART (PostgreSQL)
Разделить строку по разделителю и взять N-й элемент:
SELECT SPLIT_PART('user@example.com', '@', 1) AS username; -- 'user'
SELECT SPLIT_PART('user@example.com', '@', 2) AS domain; -- 'example.com'В MySQL: SUBSTRING_INDEX. В ClickHouse: splitByChar + array index.
Замена и конкатенация
REPLACE
SELECT REPLACE('hello world', 'world', 'SQL') AS s; -- 'hello SQL'
-- Удалить все пробелы
SELECT REPLACE(' a b c ', ' ', '') AS s; -- 'abc'CONCAT / ||
-- PostgreSQL: || игнорирует NULL? НЕТ, || с NULL → NULL
SELECT 'Hello, ' || name AS greeting FROM users;
-- CONCAT игнорирует NULL
SELECT CONCAT('Hello, ', name) FROM users;
-- CONCAT_WS — с разделителем
SELECT CONCAT_WS(' ', first_name, middle_name, last_name) FROM users;CONCAT_WS особенно полезна
Если middle_name = NULL, || выдаст NULL, CONCAT_WS пропустит NULL. Для склейки full_name это спасает.
Тренироваться на таких вопросах можно в Telegram-боте Карьерник — там 1500+ задач с реальных собесов с разборами.
Поиск и сопоставление
LIKE
SELECT * FROM users WHERE email LIKE '%@gmail.com'; -- заканчивается
SELECT * FROM users WHERE name LIKE 'А%'; -- начинается с А
SELECT * FROM users WHERE phone LIKE '+7___999%'; -- _ = любой один символВажно: LIKE чувствителен к регистру в большинстве СУБД. Для case-insensitive — ILIKE в PostgreSQL.
POSITION / INSTR
Позиция подстроки в строке:
SELECT POSITION('@' IN 'user@example.com') AS pos; -- 5
SELECT STRPOS('user@example.com', '@'); -- 5 (PostgreSQL)Возвращает 0, если не найдено.
Регулярные выражения
Сильный инструмент, спрашивают на middle-позициях.
PostgreSQL
-- Проверка
SELECT 'abc123' ~ '[0-9]+' AS has_digits; -- TRUE
-- Извлечь первое совпадение
SELECT REGEXP_MATCHES('Phone: +79991234567', '\+?\d+');
-- Заменить
SELECT REGEXP_REPLACE('Hello 123 world', '[0-9]+', 'X'); -- 'Hello X world'
-- Разбить
SELECT REGEXP_SPLIT_TO_ARRAY('a,b;c|d', '[,;|]');Проверка email
SELECT email FROM users
WHERE email ~* '^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$';Извлечение домена
SELECT SUBSTRING(email FROM '@(.+)$') AS domain FROM users;Преобразование типов
-- Строка → число
SELECT '123'::INTEGER;
SELECT CAST('3.14' AS FLOAT);
-- Число → строка
SELECT (42)::TEXT;
SELECT CAST(42 AS VARCHAR);
-- Безопасно: в PostgreSQL будет ошибка если '123abc' преобразовывать в INT
-- В ClickHouse есть toInt32OrNullЧистка данных — типовые операции
Нормализация пользовательского ввода
SELECT LOWER(TRIM(email)) AS clean_email FROM users;Удаление тегов HTML
SELECT REGEXP_REPLACE(description, '<[^>]+>', '', 'g') AS plain FROM products;Удаление всего, кроме цифр
SELECT REGEXP_REPLACE(phone, '[^0-9]', '', 'g') AS digits_only FROM users;Маска телефона
SELECT CONCAT(
'+7 (', SUBSTRING(phone FROM 2 FOR 3), ') ',
SUBSTRING(phone FROM 5 FOR 3), '-',
SUBSTRING(phone FROM 8 FOR 2), '-',
SUBSTRING(phone FROM 10 FOR 2)
) AS formatted
FROM users;К слову, набить руку на таких кейсах удобно через тренажёр в Telegram — разбирайте по 10 вопросов в день, через 2 недели тема становится рефлексом.
10 задач с собеседований
1. Извлечь домен из email
SELECT SPLIT_PART(email, '@', 2) AS domain FROM users;2. Топ-10 самых популярных доменов
SELECT SPLIT_PART(email, '@', 2) AS domain, COUNT(*)
FROM users GROUP BY 1 ORDER BY 2 DESC LIMIT 10;3. Найти пользователей с кириллицей в имени
SELECT * FROM users WHERE name ~ '[а-яА-Я]';4. Маскировать email (показать только первую букву)
SELECT LEFT(email, 1) || '***@' || SPLIT_PART(email, '@', 2) AS masked
FROM users;5. Убрать все пробелы из номера
SELECT REPLACE(phone, ' ', '') FROM users;6. Нормализовать имена (первая заглавная)
SELECT INITCAP(LOWER(name)) FROM users; -- 'JOHN doe' → 'John Doe'7. Число слов в описании
SELECT LENGTH(description) - LENGTH(REPLACE(description, ' ', '')) + 1 AS word_count
FROM products;8. Фильтр по префиксу телефона
SELECT * FROM users WHERE phone LIKE '+7%';9. Извлечь UTM-source из URL
SELECT SUBSTRING(url FROM 'utm_source=([^&]+)') AS source FROM visits;10. Найти дубликаты по нормализованному имени
SELECT LOWER(TRIM(name)), COUNT(*)
FROM users
GROUP BY LOWER(TRIM(name))
HAVING COUNT(*) > 1;Как тренироваться
Строковые функции — про запомнить 10-15 базовых. SUBSTRING, REPLACE, SPLIT_PART, POSITION, LIKE, REGEXP — ими покрываются 95% задач. Остальное гуглится.
Тренажёр Карьерник содержит блок на строковые функции: парсинг, регулярки, нормализация, очистка. Учатся за пару дней до автоматизма.
Совет: на собесе, когда показывают «очистите эту таблицу», начинайте с LOWER+TRIM — это закрывает 50% грязи. Потом переходите к REGEXP и SPLIT по ситуации.
Читайте также
FAQ
В чём разница между || и CONCAT?
|| при встрече с NULL даёт NULL (из-за чего теряется вся строка). CONCAT игнорирует NULL — заменяет на пустую строку. Для склейки full_name где любое поле может быть NULL — всегда CONCAT или CONCAT_WS.
LIKE или REGEXP?
LIKE для простых шаблонов (начинается с, заканчивается на, содержит). REGEXP — для сложных (email, номер телефона, форматы с цифрами). LIKE быстрее из-за простоты.
Как сделать case-insensitive сравнение?
Либо LOWER(col) = LOWER('value'), либо ILIKE (PostgreSQL). Первый вариант работает во всех СУБД. ILIKE использует тот же индекс, что обычный LIKE.
Есть ли STRING_AGG для склейки группы?
Да, STRING_AGG(col, ', ') в PostgreSQL, GROUP_CONCAT в MySQL. См. шпаргалку по агрегатам.