PostgreSQL-聚合查询中的聚合查询

时间:2020-09-25 22:00:15

标签: sql postgresql datetime sum where-clause

我正在为使用PostgreSQL表的销售代表佣金报告构建选择语句。我希望它显示这些列: -客户编号

-零件号

本月至今的数量(MTD数量)

-年初至今数量(年初至今数量)

-本月至今的扩展销售价格(扩展的MTD)

-年初至今的扩展销售价格(年初至今)

数据在两个表中:

Sales_History(每张发票一个记录,该表包括客户编号和发票日期)

Sales_History_Items(每张发票每个零件号一个记录,该表包括零件号,数量和单价)。

如果我做一个简单的查询,将这两个表结合在一起,它就是这样的:

日期/客户/零件/数量/单价

4月1日/ ABC公司/小部件/ 5 / $ 11

4月4日/ ABC公司/小部件/ 8 / $ 11.50

4月1日/ ABC公司/小工具/ 1 / $ 30

4月7日/ XYZ公司/小部件/ 3 / $ 11.50

这是我想要的最终结果(每个客户每个零件一行):

客户/零件/数量/ MTD数量/ MTD销售/年初至今数量/年初至今销售

ABC Co./WIDGET/13/$147/1500/$16,975

ABC Co./ GADGET / 1 / $ 30/7 / $ 210

XYZ Co./小部件/ 3 / $ 34.50 / 18 / $ 203.40

到目前为止,我已经能够提出这个SQL语句,它不会让我获得每行的扩展销售列(committed_qty * unit_price),然后按客户编号/部件号来汇总它们,这就是我的问题。问题:

with mtd as
(SELECT sales_history.cust_no, part_no, Sum(sales_history_items.committed_qty) AS MTDQty
    FROM sales_history left JOIN sales_history_items 
    ON sales_history.invoice_no = sales_history_items.invoice_no where  sales_history_items.part_no is not null and sales_history.invoice_date >= '2020-04-01' and sales_history.invoice_date <= '2020-04-30' 
    GROUP BY sales_history.cust_no, sales_history_items.part_no),

ytd as 
(SELECT sales_history.cust_no, part_no, Sum(sales_history_items.committed_qty) AS YTDQty
    FROM sales_history left JOIN sales_history_items 
    ON sales_history.invoice_no = sales_history_items.invoice_no where sales_history_items.part_no is not null and sales_history.invoice_date >= '2020-01-01' and sales_history.invoice_date <= '2020-12-31' GROUP BY sales_history.cust_no, sales_history_items.part_no),

mysummary as
(select MTDQty, YTDQty, coalesce(ytd.cust_no,mtd.cust_no) as cust_no,coalesce(ytd.part_no,mtd.part_no) as part_no
from ytd full outer join mtd on ytd.cust_no=mtd.cust_no and ytd.part_no=mtd.part_no)

select * from mysummary;

我相信我必须在这里嵌套另外两个汇总查询,这些查询将按cust_no,part_no,unit_price分组,然后将这些扩展价格总计(qty * unit_price)按cust_no,part_no求和。

任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:0)

如果我正确地关注您,则可以进行条件汇总:

select sh.cust_no, shi.part_no,
    sum(shi.qty)  mtd_qty, 
    sum(shi.qty * shi.unit_price) ytd_sales,
    sum(shi.qty) filter(where sh.invoice_date >= date_trunc('month', current_date) mtd_qty, 
    sum(shi.qty * shi.unit_price) filter(where sh.invoice_date >= date_trunc('month', current_date) mtd_sales 
from sales_history sh
left join sales_history_items shi on sh.invoice_no = shi.invoice_no 
where  shi.part_no is not null and sh.invoice_date >= date_trunc('year', current_date)
group by sh.cust_no, shi.part_no

逻辑是对当前年份进行过滤,并使用简单的汇总来计算“年初至今”的数字。要获取“迄今为止的月份”列,我们可以过滤聚合函数。

答案 1 :(得分:0)

使用filter表达式一次完成此操作:

with params as (
  select '2020-01-01'::date as year, 4 as month
)
SELECT h.cust_no, i.part_no, 
       SUM(i.committed_qty) AS YTDQty,
       SUM(i.committed_qty * i.unit_price) as YTDSales,
       SUM(i.committed_qty) FILTER 
         (WHERE extract('month' from h.invoice_date) = p.month) as MTDQty,
       SUM(i.committed_qty * i.unit_price) FILTER
         (WHERE extract('month' from h.invoice_date) = p.month) as MTDSales
  FROM params p
       CROSS JOIN sales_history h
       LEFT JOIN sales_history_items i
              ON i.invoice_no = h.invoice_no 
 WHERE i.part_no is not null 
   AND h.invoice_date >= p.year 
   AND h.invoice_date < p.year + interval '1 year' 
 GROUP BY h.cust_no, i.part_no