SQLJOINMediumБесплатно

Пары пользователей, купивших один товар

// Условие

Найдите пары пользователей, которые купили один и тот же товар (в завершённых заказах). Выведите product_id, user_id_1 (меньший) и user_id_2 (больший). Уберите дубли пар. Ограничьте результат первыми 20 строками, отсортированными по product_id, затем по user_id_1, затем по user_id_2.

// Таблицы

sandbox.orders
order_idINT
user_idINT
order_dateTIMESTAMP
amountNUMERIC(10,2)
statusVARCHAR(20)
delivery_daysINT
promo_codeVARCHAR(20)
sandbox.order_items
item_idINT
order_idINT
product_idINT
quantityINT
unit_priceNUMERIC(10,2)

// Что тренирует

SELF JOINCTEDISTINCT
▶ Решить в SQL-песочнице

// Решение

Подсказка

SELF JOIN: таблицу «пользователь-товар» соединяем саму с собой по product_id. Условие a.user_id < b.user_id убирает дубли и пару с самим собой.

Сначала попробуй сам → Показать решение
WITH user_products AS (
  SELECT DISTINCT
    o.user_id,
    oi.product_id
  FROM sandbox.orders o
  JOIN sandbox.order_items oi ON o.order_id = oi.order_id
  WHERE o.status = 'completed'
)
SELECT
  a.product_id,
  a.user_id AS user_id_1,
  b.user_id AS user_id_2
FROM user_products a
JOIN user_products b
  ON a.product_id = b.product_id
  AND a.user_id < b.user_id
ORDER BY a.product_id, a.user_id, b.user_id
LIMIT 20;

SELF JOIN — мощный паттерн. Трюк a.user_id < b.user_id решает сразу две проблемы: (1) убирает пару пользователя с самим собой (=), (2) убирает дубли — пара (1, 5) и (5, 1) превращается в одну (1, 5). CTE с DISTINCT убирает дублирование, если пользователь купил товар в нескольких заказах.

// Похожие задачи

// Разобраться в теме

→ Типы JOIN в SQL