Посчитать статистику заказов по пользователям

82. Посчитать статистику заказов по пользователям

Условие задачи:
Дана таблица orders.

Необходимо для каждого пользователя вывести:

  • общее количество заказов;
  • количество успешных заказов;
  • сумму успешных заказов;
  • дату последнего заказа.

Успешными считаются заказы со статусами PAID и SHIPPED.

Также необходимо:

  • оставить пользователей, у которых не меньше 3 заказов;
  • учитывать заказы за последние 30 дней.

Код:

CREATE TABLE orders (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    status VARCHAR(20) NOT NULL,
    amount NUMERIC(12, 2) NOT NULL,
    created_at TIMESTAMP NOT NULL
);

Спойлеры к решению

Подсказки
💡 Для группировки используй GROUP BY user_id.
💡 Общее количество заказов можно получить через COUNT(*).
💡 Для успешных заказов удобно использовать FILTER (WHERE ...).
💡 Последний заказ определяется через MAX(created_at).
💡 Условие на количество заказов после группировки задаётся через HAVING.

Решение

Для PostgreSQL:

SELECT
    user_id,
    COUNT(*) AS total_orders,
    COUNT(*) FILTER (
        WHERE status IN ('PAID', 'SHIPPED')
    ) AS successful_orders,
    COALESCE(
        SUM(amount) FILTER (
            WHERE status IN ('PAID', 'SHIPPED')
        ),
        0
    ) AS successful_amount,
    MAX(created_at) AS last_order_date
FROM orders
WHERE created_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
GROUP BY user_id
HAVING COUNT(*) >= 3;

Условие:

WHERE created_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'

оставляет только заказы за последние 30 дней.

Успешные заказы считаются через:

COUNT(*) FILTER (
    WHERE status IN ('PAID', 'SHIPPED')
)

а их сумма:

SUM(amount) FILTER (
    WHERE status IN ('PAID', 'SHIPPED')
)

MAX(created_at) возвращает дату последнего заказа, а:

HAVING COUNT(*) >= 3

оставляет только пользователей, у которых за рассматриваемые 30 дней было не меньше трёх заказов.