在 Microsoft sql 中对每个 ID 出现在多行中的值求和

sum a value that appears on multiple rows ones per id in microsoft sql

我有一个 table,如下所示。在我的查询中,我是每个订单项类型的 sum:ing 订单项值,但我不确定当 providerfee 出现在多行时如何汇总每个订单 ID 的 providerfee。 Sum(providerfee) 会给我 60 而不是 30。

原始 table(样本):

order id order item type order item value providerfee
1 Product 300 30
1 Shipping 40 30
1 Invoicefee 30 30

聚合 table 如果我用我现在使用的查询查询上面的示例 table:

noOfOrders productAmount ShippingAmount InvoiceAmount providerfee
1 300 40 30 60

我希望在聚合 table 的 providerfee 列中获得什么值:

noOfOrders productAmount ShippingAmount InvoiceAmount providerfee
1 300 40 30 30

现在有没有人从 providerfee 列中获取每个订单 ID 的正确金额的最佳实践?我认为发布我正在编写的实际查询没有任何意义,但基本上我为获取订单项目类型的金额所做的是:

    with amounts as (
        select
        case when orderItemType= 'Product' then orderItemValue else 0 end as productAmount
        ,case when orderItemType = 'Shipping' then orderItemvalue else 0 end as shippingAmount
        case when orderItemType = 'Fee' then orderItemvalue else 0 end as InvoicefeeAmount
        ,providerfee
        
    from exampleTable
    
    )
    
         select
         sum(amounts.productAmount) as productAmount
         ,sum(amounts.shippingAmount) as shippingAmount
         ,sum(amounts.invoicefeeAmount) as invoicefeeAmount
         ,sum(amounts.providerfee) as providerfeeAmount <---- This one gives me too high values since I'm summing every rows and providerfee appears on every row 

        from amounts

这是我的实际 table 样子的照片。 Providerfee 应该是 638 就像 invoiceAmount

我还尝试过的一件事是具有行号功能的逻辑。但这给了我一个结果,其中缺少三个提供者费用。我得到的不是 638,而是 551。不明白为什么,因为我计算了原始 table 并自己得到了 638。不确定我是否遗漏了一些可能对 SUM 产生影响的行号函数的逻辑。我是否应该尝试另一种功能,以便能够为每个订单 ID 仅提取一个 providerfee-row?

    with amounts as (
        select
        row_number() over (partition by orderId order by orderItemTimestamp DESC) as rn
        ,case when orderItemType= 'Product' then orderItemValue else 0 end as productAmount
        ,case when orderItemType = 'Shipping' then orderItemvalue else 0 end as shippingAmount
        ,case when orderItemType = 'Fee' then orderItemvalue else 0 end as InvoicefeeAmount
        ,providerfee
        
    from exampleTable
    
    )
    
         select
         sum(amounts.productAmount) as productAmount
         ,sum(amounts.shippingAmount) as shippingAmount
         ,sum(amounts.invoicefeeAmount) as invoicefeeAmount
         ,sum(amounts.providerfee) as providerfeeAmount <---- This one gives me too high values since I'm summing every rows and providerfee appears on every row 
         ,sum(case when (amounts.providerfee is not null and amounts.rn = 1) then amounts.providerfee else 0 end) as providerfee2

        from amounts

可以使用条件聚合来完成总计。 (请注意,我在这里希望每个订单都有一个 Invoicefee。)

select COUNT(distinct OrderId) as noOfOrders,
       SUM(case when orderItemType = 'Product'  then orderItemValue else 0 end) as productAmount,
       SUM(case when orderItemType = 'Shipping' then orderItemvalue else 0 end) as shippingAmount,
       SUM(case when orderItemType = 'Fee'      then orderItemvalue else 0 end) as InvoicefeeAmount,
       SUM(case when orderItemType = 'Fee'      then providerfee    else 0 end) as providerfee
from amounts

您还可以添加一个 GROUP BY,以获取每个订单的聚合:

select OrderId,
       SUM(case when orderItemType = 'Product'  then orderItemValue else 0 end) as productAmount,
       SUM(case when orderItemType = 'Shipping' then orderItemvalue else 0 end) as shippingAmount,
       SUM(case when orderItemType = 'Fee'      then orderItemvalue else 0 end) as InvoicefeeAmount,
       SUM(case when orderItemType = 'Fee'      then providerfee    else 0 end) as providerfee
from amounts
group by OrderId