PSQL — Агрегирование данных о продажах по срокам

#sql #postgresql

Вопрос:

Я пытаюсь придумать лучший способ написания своих сценариев. В последнее время я обнаружил, что полагаюсь на Левые объединения, чтобы выполнить многое из того, что мне нужно, и мне интересно, есть ли лучший способ писать мои сценарии.

Ниже приведен краткий пример того, что я пытался, дайте мне знать, что вы думаете.

 SELECT a.id,  SUM(a.spend) AS spend,  SUM(a.revenue) AS revenue,  SUM(b.spend) AS spend,  SUM(b.revenue),  c.product_name FROM (SELECT client, name FROM table_1) AS ACC  LEFT JOIN (SELECT revenue, spend, id FROM table_2 WHERE MONTH = 11) AS a ON acc.id = a.id  LEFT JOIN (SELECT revenue, spend, id FROM table_2 WHERE MONTH = 10) AS b ON acc.id = b.id  LEFT JOIN (SELECT product_name FROM table_3) ON a.id = c.id ORDER BY a.spend  

Комментарии:

1. не могли бы вы просто использовать регистровые выражения? sum(case when month =11 then spend else 0 end) as Spend11, sum(case when month = 11 then revenue else 0 end) as Revenue11... устранение всех левых соединений? или аналитическая сумма(случай, когда месяц=11, а затем потратить еще 0 в конце) (раздел по имени продукта) как Расход11…

2. Спасибо за сообщение xQvert, СУММА(в случае, если) Я думаю, что это тоже может сработать. Обычно я их не использую, потому что в последнее время все чаще пытаюсь использовать подзапросы. Хотя это может быть классической ошибкой новичка.

Ответ №1:

Вам не нужны эти производные таблицы (они же подзапросы или встроенные представления). Вам также не хватает GROUP BY

 SELECT a.id,  SUM(a.spend) AS spend,  SUM(a.revenue) AS revenue,  SUM(b.spend) AS spend,  SUM(b.revenue),  c.product_name FROM table_1 AS ACC  LEFT JOIN table_2 AS a ON acc.id = a.id AND a.MONTH = 11   LEFT JOIN table_2 AS b ON acc.id = b.id AND b.MONTH = 10  LEFT JOIN table_3 AS c ON a.id = c.id GROUP BY a.id, c.product_name  

Другой вариант — использовать отфильтрованную агрегацию:

 SELECT a.id,  SUM(a.spend) filter (where a.month = 11) AS spend_11,  SUM(a.revenue) filter (where a.month = 11 AS revenue_11,  SUM(a.spend) filter (where a.month = 10) AS spend_10,  SUM(a.revenue) filter (where a.month = 10) as revenue_10,  c.product_name FROM table_1 AS ACC  LEFT JOIN table_2 AS a ON acc.id = a.id AND a.MONTH in (10,11)  LEFT JOIN table_3 AS c ON a.id = c.id GROUP BY a.id, c.product_name  

Комментарии:

1. Спасибо за пост a_horse_with_no_name. Позвольте мне попробовать и посмотреть, как это работает!