-- Задание 1 SELECT name FROM mnoskov.users WHERE id IN ( SELECT user_id FROM mnoskov.orders ) ORDER BY name; -- Тут не приходится делать JOIN и DISTINCT, а просто ищем айдишник в списке -- N (подзапрос) может быть более читаемым, когда подзапрос очень простой и короткий -- Задание 2 SELECT u.id, u.name, u.email FROM mnoskov.users u WHERE NOT EXISTS ( SELECT user_id FROM mnoskov.orders o WHERE u.id = o.user_id ) -- Работает быстрее чем NOT IN -- Определить какое количество людей не делают заказы, и кинуть им например купон на скидку на первый заказ -- Задание 3 SELECT u.name, ( SELECT count(*) FROM mnoskov.orders o WHERE u.id = o.user_id ) AS orders_count FROM mnoskov.users u ORDER BY orders_count DESC, u.name; -- Подзапрос в SELECT не может возвращать несколько строк, потому что SELECT ожидает толбко одну -- Как изменится сложность запроса, если пользователей станет, например, 1 млн? Не совсем понял этот вопрос, но думаю запрос просто будет выполняться дольше -- Задание 4 WITH revenue_by_user AS ( SELECT o.user_id, sum(oi.quantity * oi.price_at_purchase) AS total_revenue FROM mnoskov.orders o JOIN mnoskov.order_items oi ON o.id = oi.order_id GROUP BY o.user_id ) SELECT u.name, rbu.total_revenue FROM mnoskov.users u JOIN revenue_by_user rbu ON u.id = rbu.user_id ORDER BY rbu.total_revenue desc; -- Проще читать когда шаг «посчитать выручку по пользователям» вынесен отдельно -- Чтобы избежать дублирования импользуется CTE, а не простой подзапрос -- Задание 5 WITH revenue_by_product AS ( SELECT product_id, sum(quantity * price_at_purchase) AS product_revenue FROM mnoskov.order_items GROUP BY product_id ) SELECT p.name, p.category, rbp.product_revenue FROM mnoskov.products p JOIN revenue_by_product rbp ON p.id = rbp.product_id ORDER BY rbp.product_revenue LIMIT 3; -- Сначала удобнее считать агрегаты, чтобы код не выгляжел грооздким и чтобы в нем было легче разобраться -- Отличае в удобстве чтения и написания. И этот агрегат можно потом ещё и переиспользовать -- Задание 6 WITH revenue_user AS ( SELECT o.user_id, sum(oi.quantity * oi.price_at_purchase) AS total_revenue FROM mnoskov.order_items oi JOIN mnoskov.orders o ON oi.order_id = o.id GROUP BY o.user_id ) SELECT u.name, u.email, ru.total_revenue FROM mnoskov.users u JOIN revenue_user ru ON u.id = ru.user_id WHERE u.is_active = TRUE AND ru.total_revenue > 10000 ORDER BY ru.total_revenue DESC, u.name; -- Я бы назвал этот сегмегт - frequent_buyers -- Таким пользователям надо предлагать какую ниюудь специальную программу лояльности -- Задание 7 WITH revenue_order AS ( SELECT order_id, sum(quantity * price_at_purchase) AS order_revenue FROM mnoskov.order_items GROUP BY order_id ) SELECT ro.order_id, o.order_date::date, ro.order_revenue FROM mnoskov.orders o JOIN revenue_order ro ON o.id = ro.order_id WHERE o.status = 'paid' AND ro.order_revenue < 10000 ORDER BY ro.order_revenue; -- Причины: злоупотребление промокодами, ошибки -- По 'paid' удобнее фильтровать снаржуи, потому тут мы подключаем orders, а подключать orders ещё и внутри было бы бессмысленно