Задачи по строкам в SQL

Проверь себя · 1/3разбор после ответа
В таблице метрик есть dt, platform, dau. Нужно вывести значение dau за предыдущий день для той же платформы, чтобы посчитать дневное изменение. Какое выражение верное?

Зачем это знать

Email parsing, URL extraction, telephone formatting — каждый аналитик работает со строками. В SQL это менее удобно чем в Python, но часто быстрее и ближе к данным.

На собесах string-задачи встречаются не в каждом SQL-туре, но в 50% — да. Уметь нужно.

Задача 1: поиск по substring

«Email содержит "@gmail.com"».

SELECT * FROM users WHERE email LIKE '%@gmail.com';

Осторожно: LIKE case-sensitive в Postgres. Use ILIKE для case-insensitive.

Задача 2: extract domain

«Выделить domain из email».

SELECT SPLIT_PART(email, '@', 2) AS domain FROM users;

Postgres. MySQL: SUBSTRING_INDEX(email, '@', -1). ClickHouse: splitByChar('@', email)[2].

Задача 3: counts по domain

SELECT
    SPLIT_PART(email, '@', 2) AS domain,
    COUNT(*) AS users_count
FROM users
GROUP BY 1
ORDER BY users_count DESC;

Задача 4: regex extract

«Выделить цифры из номера телефона».

Postgres:

SELECT REGEXP_REPLACE(phone, '[^0-9]', '', 'g') FROM users;

MySQL 8+:

SELECT REGEXP_REPLACE(phone, '[^0-9]', '') FROM users;

Задача 5: validate email

SELECT * FROM users
WHERE email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$';

Postgres. ~* — case-insensitive regex.

Задача 6: URL parsing

«Extract path из URL».

SELECT
    url,
    SPLIT_PART(url, '/', 4) AS path_first_segment
FROM page_views;

Для полного parsing обычно extension (pg_urlparse).

Задача 7: concatenation

«Full name из first + last».

SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
-- Or
SELECT first_name || ' ' || last_name AS full_name FROM users;

Осторожно с NULL: CONCAT safer (treats NULL as empty).

Задача 8: length checks

«Users с короткими passwords».

SELECT * FROM users WHERE LENGTH(password) < 8;

Задача 9: upper/lower для join

«Case-insensitive matching».

SELECT * FROM a JOIN b ON LOWER(a.email) = LOWER(b.email);

Note: blocks index usage. Better normalize при загрузке.

Прокачай SQL для собеса
500+ задач по SQL: оконные функции, JOIN, CTE — с разбором каждой
Тренировать SQL в Telegram

Задача 10: trim

«Убрать пробелы из начала/конца».

SELECT TRIM(email) FROM users;
-- Specific chars
SELECT TRIM('- ' FROM phone) FROM users;

Задача 11: replace

SELECT REPLACE(phone, '+7', '8') FROM users;

Для regex — REGEXP_REPLACE.

Задача 12: substr

SELECT SUBSTRING(email FROM 1 FOR 5) FROM users;
-- Postgres также: SUBSTRING(email, 1, 5)
-- MySQL: SUBSTR(email, 1, 5)

Задача 13: string search position

«Position символа "@" в email».

SELECT POSITION('@' IN email) FROM users;
-- Или
SELECT STRPOS(email, '@') FROM users;  -- Postgres

Задача 14: JSON в тексте

Иногда JSON хранится как строка:

SELECT payload::json->>'user_id' FROM logs;

Postgres — native JSON operators.

Задача 15: string aggregation

«Все products user в одной строке, через запятую».

SELECT
    user_id,
    STRING_AGG(product_name, ', ') AS products
FROM purchases
GROUP BY user_id;

MySQL: GROUP_CONCAT.

Частые ошибки

Case sensitivity

LIKE '%gmail%' ≠ LIKE '%Gmail%' в Postgres. Use ILIKE.

LIKE без %

WHERE email LIKE 'gmail.com' — только exact match.

Regex не универсальны

Syntax differs: Postgres, MySQL, Oracle.

Index usage

LIKE '%pattern' не использует index (leading wildcard). LIKE 'pattern%' — использует.

Performance

  • Equality быстрее LIKE
  • LIKE 'prefix%' использует index
  • LIKE '%suffix' — full scan
  • REGEX медленнее LIKE

На собесе

Strings задачи обычно:

  • Parsing (email domain, phone digits)
  • Filtering (LIKE / regex)
  • Aggregation (STRING_AGG)
  • Validation

Know 3-4 string functions в своей БД.

Связанные темы

FAQ

Regex везде?

Syntax разнится. Postgres поддерживает best среди популярных.

STRING_AGG vs LISTAGG?

STRING_AGG — Postgres. LISTAGG — Oracle, SQL Server. Same idea.

JSON как string?

Если JSON — native type → native operators. Если string — parsing manually.