JOIN в SQL на собеседовании аналитика

Почему JOIN — базовый навык аналитика

Данные в реальных проектах всегда разложены по нескольким таблицам. Пользователи, заказы, платежи, события — всё в отдельных таблицах. Любой аналитический запрос начинается с объединения этих таблиц. Поэтому JOIN спрашивают на собеседованиях любого уровня — от junior до senior.

Типичный формат вопроса: интервьюер описывает две-три таблицы и просит написать запрос или объяснить, какой результат вернёт конкретный JOIN. Кажется просто, но ловушки встречаются на каждом шагу.

JOIN — это первое, что проверяют на SQL-собеседовании. Если кандидат путает LEFT и INNER или не понимает, что происходит при дубликатах ключей — дальше могут не спрашивать.

Типы JOIN и когда что использовать

INNER JOIN — возвращает только строки, для которых есть совпадение в обеих таблицах. Это самый распространённый тип. Используется, когда нужны только записи с полным набором данных: заказы с информацией о пользователе, события с привязкой к сессии.

LEFT JOIN — возвращает все строки из левой таблицы и совпадения из правой. Если совпадения нет — в колонках правой таблицы будет NULL. Незаменим для задач типа «найти пользователей без заказов» или «показать всех сотрудников, даже тех, кто не совершил ни одной продажи».

RIGHT JOIN — зеркало LEFT JOIN, возвращает все строки из правой таблицы. На практике используется редко — обычно проще переставить таблицы местами и написать LEFT JOIN. На собеседовании могут спросить, существует ли RIGHT JOIN и когда он оправдан.

FULL OUTER JOIN — возвращает все строки из обеих таблиц. Где нет совпадения — NULL с соответствующей стороны. Используется при сверке данных из двух источников: найти записи, которые есть только в одной системе.

CROSS JOIN — декартово произведение: каждая строка одной таблицы объединяется с каждой строкой другой. Полезен для генерации комбинаций: все даты для каждого пользователя, все товары для каждого магазина.

Типичные задачи с разбором

Задача 1: Пользователи без заказов. Подход — LEFT JOIN таблицы users к orders и фильтрация WHERE orders.id IS NULL. Это классическая задача, которую дают на каждом втором собеседовании. Альтернатива — NOT EXISTS с подзапросом; интервьюер может попросить сравнить оба варианта.

Задача 2: Сотрудник и его менеджер. Подход — self-join: таблица employees объединяется сама с собой по manager_id = employee_id. Ловушка — забыть использовать LEFT JOIN, чтобы не потерять сотрудников верхнего уровня (у CEO нет менеджера).

Задача 3: Все даты в диапазоне с метриками. Подход — CROSS JOIN таблицы календаря с таблицей пользователей, затем LEFT JOIN к данным по активности. Задача проверяет, понимаете ли вы, что для «заполнения пропусков» нужно сначала создать полный набор строк.

Задача 4: Объединение данных из двух систем. Подход — FULL OUTER JOIN по общему ключу. COALESCE для выбора непустого значения из двух источников. Интервьюер проверяет, знаете ли вы, как работает FULL JOIN и зачем нужен COALESCE для ключа в результате.

Ловушки, которые ждут на собеседовании

  • Дубликаты при JOIN — если в правой таблице несколько строк с одним ключом, LEFT JOIN размножит строки левой таблицы. Это частая причина неправильных сумм и подсчётов. Интервьюер может дать таблицы с дубликатами и спросить, сколько строк вернёт запрос.
  • LEFT JOIN + WHERE на правой таблице — условие WHERE right_table.column = 'value' фактически превращает LEFT JOIN в INNER JOIN, потому что отсеивает NULL-строки. Правильное решение — перенести условие в ON.
  • NULL в ключах JOIN — NULL не равен ничему, включая другой NULL. Строки с NULL в колонке JOIN никогда не объединятся. Это ловушка, о которой забывают даже опытные аналитики.
  • Порядок таблиц в JOIN — для INNER JOIN порядок не важен, для LEFT JOIN — критичен. Перепутать левую и правую таблицу — значит получить совершенно другой результат.

Самая частая ловушка на собеседовании: LEFT JOIN с фильтром WHERE на правой таблице. Если видите такую конструкцию — перенесите условие в ON или используйте подзапрос.

Self-join: отдельная тема

Self-join — объединение таблицы с самой собой — заслуживает отдельного внимания. Это не отдельный тип JOIN, а паттерн использования. Применяется для иерархий (сотрудник — менеджер), сравнения строк внутри одной таблицы (заказ пользователя с его предыдущим заказом), поиска пар (пользователи из одного города).

На собеседовании self-join проверяет, умеете ли вы мыслить нестандартно. Ключ — правильно задать алиасы: один для «левой» копии таблицы, другой для «правой».

Как готовиться

Начните с того, чтобы нарисовать диаграмму Венна для каждого типа JOIN — это поможет интуитивно понять, какие строки попадут в результат. Затем решайте задачи: сначала на два типа JOIN в одном запросе, потом на три таблицы, потом с self-join.

Помимо JOIN, на SQL-собеседованиях часто спрашивают оконные функции и GROUP BY с HAVING. Полный список тем — в разделе вопросы по SQL.

FAQ

Чем LEFT JOIN отличается от INNER JOIN?

INNER JOIN возвращает только строки с совпадением в обеих таблицах. LEFT JOIN возвращает все строки из левой таблицы — если в правой нет совпадения, колонки правой таблицы заполняются NULL. На практике LEFT JOIN нужен, когда важно сохранить все записи из основной таблицы, даже если связанных данных нет.

Когда нужен FULL OUTER JOIN?

FULL OUTER JOIN используется при сверке двух наборов данных: найти записи, которые есть только в первой таблице, только во второй, или в обеих. Типичный сценарий — сравнение данных из двух систем или аудит: какие заказы есть в CRM, но отсутствуют в биллинге, и наоборот.

Как избежать дубликатов при JOIN?

Убедитесь, что ключ JOIN уникален хотя бы в одной из таблиц. Если дубликаты неизбежны — агрегируйте данные до JOIN (через подзапрос или CTE) или используйте DISTINCT после. На собеседовании всегда уточняйте у интервьюера, уникален ли ключ — это показывает зрелость мышления.

Смотрите также