Урок по треку Системный анализ 7 мин

SQL, который нужен системному аналитику

Выборки, JOIN, агрегаты и окна на PostgreSQL: проверка гипотез и данных.

На собесе СА почти всегда есть 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?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.