Вы сделали LEFT JOIN users → events по user_id, чтобы сохранить пользователей без событий. Как корректно посчитать количество пользователей на соединённой таблице, не попавшись в ловушку дублирования строк?
AИспользовать
COUNT(DISTINCT user_id), чтобы получить число уникальных пользователей и не дублировать их по числу совпавших событий.BИспользовать
COUNT(*), считая, что после LEFT JOIN число строк автоматически равно числу пользователей в исходной таблице слева.CИспользовать
COUNT(event_id), считая, что строки с NULL справа всё равно учтутся в счётчике пользователей без событий.DИспользовать
SUM(event_id), считая, что сумма идентификаторов корректно отражает количество уникальных пользователей в результате.Правильный ответ. После
LEFT JOIN к таблице с отношением «один-ко-многим» пользователи дублируются, поэтому для подсчёта пользователей нужен COUNT(DISTINCT user_id).Разбор
LEFT JOIN сохраняет всех пользователей, но добавляет по строке на каждое совпавшее событие, создавая дубли. COUNT(*) в таком наборе ближе к числу событий, а COUNT(event_id) игнорирует строки без событий, где справа NULL. COUNT(DISTINCT user_id) возвращает число уникальных пользователей, включая тех, у кого нет ни одного события. Это и есть корректный ответ для метрики числа пользователей.
Проверь себя · 1/3разбор после ответа
Хотите посчитать конверсию «пользователь посмотрел товар → пользователь купил» по
user_id. Данные: таблица событий (много просмотров на пользователя) и таблица заказов (много заказов на пользователя). Что корректнее всего сделать, чтобы избежать искажения «многие-ко-многим»?Ещё вопросы по теме «JOIN и кардинальность»
- В таблице `users` 100 000 строк, в таблице `user_profiles` — ровно одна строка на каждого `user_id`. Вы делаете `INNER JOIN` по `user_id`. Что верно про число строк результата?
- Вы соединяете таблицы пользователей и заказов по `user_id`, где у одного пользователя может быть много заказов (связь «один ко многим»). Как посчитать число пользователей, которые сделали хотя бы один заказ, и не получить дубли?
- Для одного `order_id` в `order_items` есть 3 строки, а в `payments` — 2 строки. Вы соединили обе таблицы по `order_id` без предварительной агрегации. Сколько строк получится для этого заказа и почему?
- Нужен набор данных на уровне `user_id`: выручка из `orders` и число сессий из `sessions`. В обеих таблицах по пользователю много строк (один-ко-многим). Какой подход минимизирует риск размножения строк в соединении?
- Вы хотели посчитать средний чек по заказам как `AVG(order_total)`. Но перед этим соединили `orders` с `order_items` по `order_id` (связь один-ко-многим). Почему `AVG()` может измениться по сравнению с расчётом на таблице `orders`?
- Все вопросы по «JOIN и кардинальность» →