Найти в Дзене
Информатика

Почему Spotify знает, что ты захочешь послушать завтра — и при чём тут LEFT JOIN

Когда TikTok решает, какое видео показать тебе следующим, — это не магия и не «ИИ» в том смысле, в каком его любят пиарить. В основе — запрос к базе данных. Конкретный, хирургически точный запрос, который за миллисекунды собирает из разных таблиц информацию о тебе, твоих интересах, времени суток и ещё паре сотен параметров. И в этом запросе, почти наверняка, есть JOIN. Представь, что у маркетплейса есть список всех зарегистрированных пользователей. И отдельно — список заказов. Логика подсказывает: соедини их и получи картину. Но вот засада: не все пользователи что-то купили. Часть зашла, посмотрела и ушла. И если ты используешь обычный INNER JOIN — эти люди просто исчезнут из результата. Как будто их не существует. А они существуют. И именно они — главный объект для аналитика. Почему не купили? Что смотрели? На каком шаге ушли? Вот тут и появляется LEFT JOIN. SELECT
c.name,
COUNT(o.order_id) AS order_count
FROM customers AS c
LEFT JOIN orders AS o ON c.customer_id = o.customer_
Оглавление
Два мира, одна таблица
Два мира, одна таблица

Начнём с неочевидного

Когда TikTok решает, какое видео показать тебе следующим, — это не магия и не «ИИ» в том смысле, в каком его любят пиарить. В основе — запрос к базе данных. Конкретный, хирургически точный запрос, который за миллисекунды собирает из разных таблиц информацию о тебе, твоих интересах, времени суток и ещё паре сотен параметров.

И в этом запросе, почти наверняка, есть JOIN.

Два мира, одна таблица

Представь, что у маркетплейса есть список всех зарегистрированных пользователей. И отдельно — список заказов. Логика подсказывает: соедини их и получи картину.

Но вот засада: не все пользователи что-то купили. Часть зашла, посмотрела и ушла. И если ты используешь обычный INNER JOIN — эти люди просто исчезнут из результата. Как будто их не существует.

А они существуют. И именно они — главный объект для аналитика. Почему не купили? Что смотрели? На каком шаге ушли?

Вот тут и появляется LEFT JOIN.

SELECT
c.name,
COUNT(o.order_id) AS order_count
FROM customers AS c
LEFT JOIN orders AS o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.name
ORDER BY order_count DESC;

Этот запрос вернёт всех клиентов — и тех, кто купил десять раз, и тех, кто не купил ни разу. У последних в колонке заказов будет 0. Не пустота, не ошибка — аналитически значимый ноль.

NULL — это не баг, это сигнал

отсутствие данных как информация
отсутствие данных как информация

Когда LEFT JOIN не находит совпадения в правой таблице, он возвращает NULL. Многие новички пугаются: что-то сломалось?

Нет. NULL — это данные об отсутствии данных. Звучит как буддийская притча, но это чистая прагматика.

Пользователь зарегистрировался, но ни одного заказа нет → NULL в колонке order_id. Это значит: человек в системе есть, но до конверсии мы его не довели. Это сигнал для продуктовой команды, для маркетинга, для A/B теста.

-- Найти всех, кто зарегистрировался, но ничего не купил
SELECT c.name
FROM customers AS c
LEFT JOIN orders AS o ON c.customer_id = o.customer_id
WHERE o.order_id IS NULL;

Один запрос — и у тебя список потенциальных покупателей для ретаргетинга. Вот так SQL становится частью воронки продаж.

«Данные — это новая нефть». Но только если ты умеешь их добывать.

Почему COUNT(*) — это ловушка

корректный и некорректный подсчёт
корректный и некорректный подсчёт

Маленький инсайт, который экономит много нервов.

Когда считаешь заказы через LEFT JOIN, важно писать COUNT(o.order_id), а не COUNT(*).

COUNT(*) считает все строки подряд — включая те, где заказов нет, но строка всё равно появилась из-за LEFT JOIN. Получишь 1 вместо 0 для клиентов без заказов. Тихая ошибка, которая ломает отчёт.

COUNT(o.order_id) — умнее. Он игнорирует NULL и считает только реальные значения.

Это один из тех моментов, когда понимание как работает SQL важнее знания синтаксиса.

А RIGHT JOIN вообще нужен?

переворот логики
переворот логики

Технически — да. На практике — почти никогда.

Любой RIGHT JOIN можно переписать как LEFT JOIN, просто поменяв таблицы местами. Большинство команд так и делают — ради читаемости. Когда видишь LEFT JOIN, мозг сразу понимает: вот главная таблица, вот дополнение к ней. С RIGHT JOIN приходится мысленно переворачивать логику.

Код читают люди. Пиши для людей.

Где это реально используется

аналитика, рекомендации, воронка
аналитика, рекомендации, воронка

Spotify — рекомендации строятся на анализе того, что ты не слушал из похожего профиля. LEFT JOIN + IS NULL = основа коллаборативной фильтрации.

Финтех — банки ищут клиентов без активных продуктов. Кто есть в базе, но не пользуется кредитом? Одним запросом — список для звонка менеджера.

Геймдев — анализ оттока: кто заходил в игру месяц назад, но не заходил на этой неделе? LEFT JOIN двух периодов и фильтр по NULL.

Маркетплейсы — товары без продаж, продавцы без отзывов, категории без трафика. Всё это — задачи на внешние соединения.

Итог, который стоит запомнить

LEFT JOIN — это не просто команда. Это способ думать об отсутствии: кого нет в воронке, какие данные выпадают, где теряется бизнес.

Когда ты понимаешь, что NULL — это сигнал, а не ошибка, и что COUNT(столбец) умнее COUNT(*) — ты начинаешь думать как аналитик, а не как человек, который просто выучил синтаксис.

Разница между этими двумя — примерно как между тем, кто умеет гуглить, и тем, кто понимает, что именно гуглить.

🔎 Хочешь копнуть глубже? Полный учебный материал с детальными примерами, схемами и крутыми иллюстрациями ждёт тебя на нашем сайте!