На собесе СА почти всегда есть SQL: 2-4 задачи на JOIN, GROUP BY, иногда окна. В работе SQL нужен, чтобы проверить гипотезу на данных, найти причину бага, подготовить выборку для заказчика, оценить объёмы перед проектированием.
Порядок выполнения запроса
SELECT -- 5. какие колонки
FROM -- 1. откуда
JOIN -- 1. соединения
WHERE -- 2. фильтр строк
GROUP BY -- 3. группировка
HAVING -- 4. фильтр групп
ORDER BY -- 6. сортировка
LIMIT -- 7. сколько строк
Поэтому в WHERE нельзя использовать агрегат и псевдоним из SELECT, а в HAVING можно агрегат.
JOIN
INNER JOIN: только совпавшие пары.LEFT JOIN: все строки слева, справа NULL, если пары нет. Главный инструмент поиска «у кого нет»: клиенты без заказов, заявки без ответа.- Условие на правую таблицу в
WHEREпревращаетLEFT JOINвINNER. Переносите его вON.
-- клиенты без единого оплаченного заказа
SELECT c.id, c.name
FROM clients c
LEFT JOIN orders o ON o.client_id = c.id AND o.status = 'paid'
WHERE o.id IS NULL;
NULL
NULL = NULLдаёт не true, а NULL. Проверка толькоIS NULL.COUNT(*)считает строки,COUNT(col)только не NULL.NOT IN (подзапрос с NULL)возвращает пустоту. ИспользуйтеNOT EXISTS.
Агрегаты
SELECT status, COUNT(*) AS cnt, SUM(amount) AS total
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY status
HAVING COUNT(*) > 10;
Условная агрегация через FILTER (PostgreSQL) или CASE:
SELECT COUNT(*) FILTER (WHERE status = 'paid') AS paid,
COUNT(*) FILTER (WHERE status = 'cancelled') AS cancelled
FROM orders;
CTE и оконные функции
WITH делает запрос читаемым. Окна считают по группе, не схлопывая строки:
SELECT client_id, id, created_at,
ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY created_at) AS n
FROM orders;
n = 1 это первый заказ каждого клиента. Так решают задачи «последний статус заявки», «топ-3 в категории», «время между событиями» (LAG).
Аналитик и данные: типовые задачи
- Проверка гипотезы: «у скольких заявок нет ответа больше суток?»
- Качество данных: дубли по email, сироты без родителя, недопустимые статусы.
- Объёмы: сколько строк в день, распределение по статусам.
- Сверка интеграции: какие заказы есть у нас и нет у партнёра (
FULL JOINилиEXCEPT).
Частые ошибки
- Задвоение сумм после JOIN двух таблиц «один ко многим».
- Деление целых:
1 / 2 = 0. Приведите кnumeric. - Даты:
created_at <= '2026-01-31'дляtimestampтеряет весь день 31-го, кроме полуночи. Пишите< '2026-02-01'. DISTINCTкак пластырь от задвоения вместо исправления JOIN.
Что спросят на собесе
- Порядок выполнения SELECT.
- Разница WHERE и HAVING.
- Найди клиентов без заказов двумя способами.
- Как найти дубли?
- Что такое оконная функция и чем она отличается от GROUP BY?