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

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

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

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 при загрузке.

Задача 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.


Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.