将各项加在一起,但分别计算,组和子组?

问题描述

我希望将每个月的项目对(顶部+基本)的总和金额总计,而仅将该对计算为1个单位。似乎很容易吧?

唯一的缺点是单个底座可以与多个顶部(多个零件编号)配对,并且这些收入需要在每个不同顶部(零件编号)上分组。

1000T底座可搭配顶部052和952。 9000T底座可以搭配顶部087和787。

销售订单表:

order_num  |  part_num  |  month  |  quantity  |  revenue
01            052         January       1          4000
01            1000T       January       1          2000
02            052         January       1          4000
02            1000T       January       1          2000
03            087         January       1          5000
03            9000T       January       1          2500
04            087         January       1          5000
04            9000T       January       1          2500
05            787         February      1          5500
05            9000T       February      1          2500
06            952         January       1          3000
06            1000T       January       1          2000

我需要:

part_num  |  month  |  quantity  |  revenue
052         January       2          12000
952         January       1          5000
087         January       2          15000
787         January       0          0
787         February      1          8000

如果我在part_num上分组,那么我的基础将从顶部分开。我无法总结销售订单,因为某些销售订单包含不同的产品(尽管此处不是我的示例)。当他们的销售订单编号匹配时,我需要对top + base组合的每次出现求和,对吗?我可以在excel中做一些等效的SUMPRODUCT来获得组合的数组,然后对它们求和吗?感谢您的帮助。

解决方法

样本数据

为了方便按时间顺序排序,我将月份更改为整数。

<!DOCTYPE html>
<html>
  <head>
    <title>Page Title</title>
  </head>
  <body>
    <label for="btn" class="icon">
      <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX///8AAADPz8+WlpZLS0v7+/vu7u5vb29TU1PDw8Pz8/N8fHyCgoITExMzMzOsrKyPj4+6urrU1NTo6Oizs7NCQkJkZGQoKCilpaUtLS05OTmenp7IyMiFhYVaWlpqamoLCwt+baPtAAACfUlEQVR4nO3di27CMAyF4TBWoAxYx2UX2Abv/5RbpSE2aXLSJpJl5/+ewEdQSlLXCQEAAAAAAAAAAAAAAAAA/Fu2H5/3dnyu2uWgfLv5xJ75Ljlf02kXO1LXpAWcHbQrHe0wSwm4XGvXmWGdcDU2G+0qs2ziX9SVdo2ZVrGAW+0Ks20jCZ+1C8z2LAecaddXgPx7+qhdXgGPYsKzdnkFnMWEL9rlFfAiJrxol1eCmFC7uCLEhJb/sV2txYT32uUVcBATWl03/daJCd+1yyvgXUzo4Mf0IgcMr9oFZnuNJGzetCvM9BZdIFq/EiNXof3v6SkeMISpdpUZpikBQ3jSrnO0p7SA3+tgixvCk8k8aS/xx2561K53oGOXvuV9Dbm9s2M7OB4AAAAAAAAAALBj2Z6mdpwGvm4Rmv1C+1nSYIt94rsIvdZmN/umTQ34oF3qaA9pAe19QW8WKQFtPuG+mscDWu/0lru8g4dm/Vi7gvVXZqIvzTTa9RUg3xbtNgvdyG1Ddm+FN/JN0Vqf0H82YkL7LcKxJmHt6oqo/DO0uaj46ygm9P9b6v9+6P8/jf//pRWsLfyvDytY41ewT2P5ppi411bBfmkFe949588tAAAAAAAAAACAJc7nRO06aw/Yhs36mtkcen1Onte21y51tMSZe+7nJp60q8ySMPvS/fzSxvrc+egMWtvzWXuxOcLa9RXg+yrsyVei/5nsdg+zupHn6vs/G0G7uiIqT2j9ft+Tz5mxuWz6Sz4ryHqXd0/u9Lbfqh9t1nd/7loFZ+eZf2kmev5hBWdY+j+HtIKzZCs4Dzj4P9O5Z+1c7g9euAAAAAAAAAAAAAAAAABQhS+ZyFZoP93BCgAAAABJRU5ErkJggg=="></label>
  </body>
</html>

解决方案

因为您还希望月销售额为零,所以从两个常用表表达式(declare @SalesOrder table ( num nvarchar(2),prt nvarchar(5),mth int,qty int,rev int ); insert into @SalesOrder (num,prt,mth,qty,rev) values ('01','052',1,4000),('01','1000T',2000),('02',('03','087',5000),'9000T',2500),('04',('05','787',2,5500),('06','952',3000),2000); cte_topPrt)中分别提取数据中的前半部分和前半个月,然后将它们组合在一起以得到全部组合。

cte_mth

结果

这里的行比您所描述的输出要多,但是您没有提供任何条件来对结果行进行过滤或排序。

with cte_topPrt as -- collect all top parts
(
    select distinct so.prt
    from @SalesOrder so
    where right(so.prt,1) <> 'T'
),cte_mth as -- collect all months (because you also want to see months with 0 sales)
(
    select distinct so.mth
    from @SalesOrder so
)
select  tp.prt as [part_num],m.mth as [month],coalesce(sum(case when so_tp.prt = so_c.prt then so_tp.qty else 0 end),0) as [quantity],coalesce(sum(so_c.rev),0) as [revenue]
from cte_topPrt tp
cross join cte_mth m
left join @SalesOrder so_tp -- sales order top part
    on  so_tp.prt = tp.prt
    and so_tp.mth = m.mth
left join @SalesOrder so_c -- sales order complete
    on so_c.num = so_tp.num
group by tp.prt,m.mth
order by m.mth,tp.prt;
,

这将从匹配的顶部和底部获得数量和收入。如果订单上还有其他内容,这很重要。

;
with SalesOrder as (
    select order_num,part_num,[month],quantity,revenue
    from (
        values ('01','January','44',20000),'February',2000)
     ) as so(
        order_num,revenue
    )
),tops as (
    select part_num,base_part_num
    from (
        values ('052','1000T'),('952',('087','9000T'),('787','9000T')
    ) as t(
        part_num,base_part_num
    )
),months as (
    select 1 as MonthNumber,datename(month,'2000' + FORMAT(1,'00') + '01') as MonthName
    
    union all
    select m.MonthNumber + 1,'2000' + FORMAT(m.MonthNumber + 1,'00') + '01')
    from months m
    where m.MonthNumber < 12
)


select x.part_num,x.MonthName,coalesce(o.quantity,0) as quantity,coalesce(o.revenue,0) as revenue

from (
    select so.part_num,so.month,sum(so.quantity) as quantity,sum(so.revenue + baseorder.revenue) as revenue

    from SalesOrder so
      inner join tops t on t.part_num = so.part_num
      inner join SalesOrder baseorder on baseorder.part_num = t.base_part_num
                                     and baseorder.order_num = so.order_num

    group by so.part_num,so.month
) o
  full outer join (
    select m.MonthName,m.MonthNumber,t.part_num
    from months m,tops t
  ) x on x.part_num = o.part_num
     and x.MonthName = o.month

order by x.MonthNumber,x.part_num

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...