← Назад к вопросам
SQL: Найти пользователей, купивших товар с id=5 после 10 октября
1.0 Junior🔥 271 комментариев
#SQL и базы данных
Условие
Есть таблица purchases:
- purchase_id (integer)
- user_id (integer)
- product_id (integer)
- purchase_date (date)
Вывести количество людей, которые покупали товар с id = 5 после 10 октября 2021 (включительно).
Ожидаемый результат:
Одно число - количество уникальных пользователей.
Источник: собеседование на аналитика в Альфа-банк
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение: Пользователи, купившие товар с id=5
Базовый SQL-запрос
SELECT COUNT(DISTINCT user_id) as unique_users
FROM purchases
WHERE product_id = 5
AND purchase_date >= '2021-10-10';
Объяснение
Ключевые элементы:
-
COUNT(DISTINCT user_id) — считаем уникальных пользователей
- DISTINCT убирает дубликаты (если один пользователь купил товар дважды, считаем один раз)
- Если просто COUNT(*), получим количество покупок, а не пользователей
-
WHERE product_id = 5 — фильтруем только товар с id=5
-
WHERE purchase_date >= '2021-10-10' — дата 10 октября 2021 включительно
- Оператор >= означает "больше или равно", что включает саму дату 10.10.2021
Пример
Исходные данные:
purchase_id | user_id | product_id | purchase_date
-----------|---------|-----------|--------------
1 | 101 | 5 | 2021-10-10
2 | 102 | 5 | 2021-10-11
3 | 101 | 5 | 2021-10-15 (второй раз)
4 | 103 | 5 | 2021-09-30 (исключён)
5 | 104 | 3 | 2021-10-10 (другой товар)
Результат:
unique_users
3
Почему 3? Потому что:
- user_id 101 → 2 покупки, но считаем 1 раз
- user_id 102 → 1 покупка
- user_id 103 → исключён (дата 2021-09-30 < 2021-10-10)
- user_id 104 → исключён (product_id = 3, а не 5)
Итого: 3 уникальных пользователя (101, 102, со сдвигом)
Альтернативные варианты
Вариант 1: С явным указанием даты как TIMESTAMP
SELECT COUNT(DISTINCT user_id) as unique_users
FROM purchases
WHERE product_id = 5
AND purchase_date >= '2021-10-10'::date;
Вариант 2: С функцией DATE
SELECT COUNT(DISTINCT user_id) as unique_users
FROM purchases
WHERE product_id = 5
AND DATE(purchase_date) >= DATE('2021-10-10');
Вариант 3: С информацией о количестве покупок
SELECT
user_id,
COUNT(*) as purchase_count
FROM purchases
WHERE product_id = 5
AND purchase_date >= '2021-10-10'
GROUP BY user_id
ORDER BY purchase_count DESC;
Результат:
user_id | purchase_count
--------|----------------
101 | 2
102 | 1
Вариант 4: Итого со счётом
SELECT
COUNT(DISTINCT user_id) as unique_users,
COUNT(*) as total_purchases,
ROUND(COUNT(*) :: NUMERIC / COUNT(DISTINCT user_id), 2) as avg_purchases_per_user
FROM purchases
WHERE product_id = 5
AND purchase_date >= '2021-10-10';
Результат:
unique_users | total_purchases | avg_purchases_per_user
-------------|-----------------|----------------------
3 | 4 | 1.33
Почему DISTINCT важен
-- ❌ Неправильно (считает покупки, не пользователей)
SELECT COUNT(*) FROM purchases WHERE product_id = 5;
-- Результат: может быть 4 (если один пользователь купил 2 раза)
-- ✅ Правильно (считает уникальных пользователей)
SELECT COUNT(DISTINCT user_id) FROM purchases WHERE product_id = 5;
-- Результат: 3 (каждый пользователь считается один раз)
Оптимизация для больших таблиц
Для таблиц с миллионами строк добавьте индекс:
CREATE INDEX idx_purchases_product_date
ON purchases(product_id, purchase_date);
Этот индекс ускорит WHERE и позволит базе эффективнее подсчитывать DISTINCT.