У меня есть (сильно упрощенная) таблица заказов, total
- сумма в долларах, содержащая:
| id | client_id | type | total |
|----|-----------|--------|-------|
| 1 | 1 | sale | 100 |
| 2 | 1 | refund | 100 |
| 3 | 1 | refund | 100 |
И таблица клиентов, содержащая:
| id | name |
|----|------|
| 1 | test |
Я пытаюсь создать разбивку по клиенту, метрики об общем количестве продаж, возвратах, сумме продаж, сумме возвратов и т. д. c.
Для этого я запрашиваю таблицу клиентов и присоединяюсь к таблице заказов. Таблица заказов содержит как продажи, так и возвраты, указанные в столбце type
.
Моя идея состояла в том, чтобы дважды объединить заказы с помощью подзапросов и создать псевдонимы для этих отфильтрованных таблиц. Затем псевдонимы будут использоваться в агрегатных функциях для нахождения суммы, среднего и т. Д. c. Я пробовал много вариантов присоединения к таблице заказов дважды, чтобы добиться этого, но это приводит к тем же неверным результатам. Этот запрос демонстрирует эту идею:
SELECT
clients.*,
SUM(sales.total) as total_sales,
SUM(refunds.total) as total_refunds,
AVG(sales.total) as avg_ticket,
COUNT(sales.*) as num_of_sales
FROM clients
LEFT JOIN (SELECT * FROM orders WHERE type = 'sale') as sales
ON sales.client_id = clients.id
LEFT JOIN (SELECT * FROM orders WHERE type = 'refund') as refunds
ON refunds.client_id = clients.id
GROUP BY clients.id
Результат:
| id | name | total_sales | total_refunds | avg_ticket | num_of_sales |
|----|------|-------------|---------------|------------|--------------|
| 1 | test | 200 | 200 | 100 | 2 |
Ожидаемый результат:
| id | name | total_sales | total_refunds | avg_ticket | num_of_sales |
|----|------|-------------|---------------|------------|--------------|
| 1 | test | 100 | 200 | 100 | 1 |
Когда второе соединение включено в запрос, строки возвращаются из первого соединения возвращаются снова со вторым соединением. Они умножаются на количество строк во втором соединении. Ясно, что мое понимание присоединения и / или подзапросов неполно.
Я понимаю, что могу фильтровать таблицу заказов по каждой статистической функции. Это дает правильные результаты, но кажется неэффективным:
SELECT
clients.*,
SUM(orders.total) FILTER (WHERE type = 'sale') as total_sales,
SUM(orders.total) FILTER (WHERE type = 'refund') as total_refunds,
AVG(orders.total) FILTER (WHERE type = 'sale') as avg_ticket,
COUNT(orders.*) FILTER (WHERE type = 'sale') as num_of_sales
FROM clients
LEFT JOIN orders
on orders.client_id = clients.id
GROUP BY clients.id
Каков подходящий способ создания отфильтрованных и псевдонимов версий этой объединенной таблицы?
Кроме того, что именно происходит с моим начальным запросом, где два подзапроса объединены. Я ожидал бы, что они будут рассматриваться как отдельные подмножества, даже если они работают на одной и той же таблице (заказов).