← Назад к вопросам

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';

Объяснение

Ключевые элементы:

  1. COUNT(DISTINCT user_id) — считаем уникальных пользователей

    • DISTINCT убирает дубликаты (если один пользователь купил товар дважды, считаем один раз)
    • Если просто COUNT(*), получим количество покупок, а не пользователей
  2. WHERE product_id = 5 — фильтруем только товар с id=5

  3. 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.