【问题标题】:Sum items together but count separately, groups and subgroups?将项目加在一起但单独计算,组和子组?
【发布时间】:2023-03-10 08:03:02
【问题描述】:

我希望将每个月的物品对(顶部 + 底部)的金额相加,同时仅将该对计为 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 得到一个组合数组,然后对每个组合求和吗?感谢您的帮助。

【问题讨论】:

  • 那么“top”和“base”与你提供的数据有什么关系?
  • 部件号 087、787、052 和 952 是顶部。零件编号 1000T 和 2000T 是基础。我想我并不清楚这一点。这是配对在一起的两类项目。
  • 您的样本数据可能缺乏必要的复杂性。如果客户订购 787 顶部和 1000T 底座怎么办? ...一个订单上的两个顶部和一个底部?
  • 这是不可能的,我们不允许客户订购没有底座的顶部。如果为顶部订购替换底座,则会获得不同的名称(1000T > 1000T-P)。

标签: sql sql-server accounting


【解决方案1】:

样本数据

最后我把月份改成了整数,以便于按时间顺序排序。

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, 1, 4000),
('01', '1000T', 1, 1, 2000),
('02', '052',   1, 1, 4000),
('02', '1000T', 1, 1, 2000),
('03', '087',   1, 1, 5000),
('03', '9000T', 1, 1, 2500),
('04', '087',   1, 1, 5000),
('04', '9000T', 1, 1, 2500),
('05', '787',   2, 1, 5500),
('05', '9000T', 2, 1, 2500),
('06', '952',   1, 1, 3000),
('06', '1000T', 1, 1, 2000);

解决方案

因为您还想要销售额为零的月份,所以顶部部分和月份分别从两个公用表表达式(cte_topPrtcte_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;

结果

此处的行数比您描述的输出中的多,但您没有提供任何条件来过滤或排序结果行。

part_num month       quantity    revenue
-------- ----------- ----------- -----------
052      1           2           12000
087      1           2           15000
787      1           0           0
952      1           1           5000
052      2           0           0
087      2           0           0
787      2           1           8000
952      2           0           0

【讨论】:

    【解决方案2】:

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

    ;
    with SalesOrder as (
        select order_num
            ,part_num
            ,[month]
            ,quantity
            ,revenue
        from (
            values ('01', '052',   'January',  1, 4000)
                 , ('01', '1000T', 'January',  1, 2000)
                 , ('01', '44',    'January',  1, 20000)
                 , ('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)
         ) as so(
            order_num,
            part_num,
            [month],
            quantity,
            revenue
        )
    ),
    tops as (
        select part_num
        , base_part_num
        from (
            values ('052', '1000T')
                 , ('952', '1000T')
                 , ('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
        , datename(month, '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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 2012-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多