Postgresql - 在聚合查询中聚合查询
Postgresql - Aggregate queries inside aggregate queries
我正在为使用 postgresql tables 的销售代表佣金报告构建一个 select 语句。我希望它显示这些列:
-客户编号
-零件号
-月初至今的数量(MTD 数量)
-年初至今数量(YTD 数量)
-月初至今的扩展售价(MTD 扩展)
-年初至今的扩展售价(YTD 扩展)
数据在两个table中:
Sales_History(每张发票一条记录,此 table 包括客户编号和发票日期)
Sales_History_Items(每张发票每个零件号一条记录,这 table 包括零件号、数量和单价)。
如果我做一个结合这两个 table 的简单查询,这就是它的样子:
日期/客户/零件/数量/单价
4 月 1 日/ABC Co./WIDGET/5/11 美元
4 月 4 日/ABC Co./WIDGET/8/11.50 美元
4 月 1 日 / ABC 公司 / 小工具 / 1 / 30 美元
4 月 7 日/XYZ Co./WIDGET/3/11.50 美元
等
这是我想要的最终结果(每个客户每个零件一行):
客户/零件/数量/MTD 数量/MTD 销售额/YTD 数量/YTD 销售额
ABC 公司/WIDGET/13/147 美元/1500 美元/16,975 美元
ABC 公司 / 小工具 / 1 / $30 / 7 / $210
XYZ 公司/WIDGET/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.
总结
如有任何帮助,我们将不胜感激。谢谢!
如果我没看错的话,你可以做条件聚合:
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
逻辑是过滤当前年份,并使用简单的聚合来计算“年初至今”的数字。要获得“月初至今”列,我们只需过滤聚合函数即可。
使用 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
我正在为使用 postgresql tables 的销售代表佣金报告构建一个 select 语句。我希望它显示这些列: -客户编号
-零件号
-月初至今的数量(MTD 数量)
-年初至今数量(YTD 数量)
-月初至今的扩展售价(MTD 扩展)
-年初至今的扩展售价(YTD 扩展)
数据在两个table中:
Sales_History(每张发票一条记录,此 table 包括客户编号和发票日期)
Sales_History_Items(每张发票每个零件号一条记录,这 table 包括零件号、数量和单价)。
如果我做一个结合这两个 table 的简单查询,这就是它的样子:
日期/客户/零件/数量/单价
4 月 1 日/ABC Co./WIDGET/5/11 美元
4 月 4 日/ABC Co./WIDGET/8/11.50 美元
4 月 1 日 / ABC 公司 / 小工具 / 1 / 30 美元
4 月 7 日/XYZ Co./WIDGET/3/11.50 美元
等
这是我想要的最终结果(每个客户每个零件一行):
客户/零件/数量/MTD 数量/MTD 销售额/YTD 数量/YTD 销售额
ABC 公司/WIDGET/13/147 美元/1500 美元/16,975 美元
ABC 公司 / 小工具 / 1 / $30 / 7 / $210
XYZ 公司/WIDGET/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.
总结如有任何帮助,我们将不胜感激。谢谢!
如果我没看错的话,你可以做条件聚合:
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
逻辑是过滤当前年份,并使用简单的聚合来计算“年初至今”的数字。要获得“月初至今”列,我们只需过滤聚合函数即可。
使用 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