【问题标题】:Calculating TOTAL of certain items using CASE and OVER使用 CASE 和 OVER 计算某些项目的 TOTAL
【发布时间】:2015-10-14 05:12:51
【问题描述】:

我需要计算特定产品代码的总值。产品代码为 5780 和低于 5700 的所有内容。

要计算我使用代码的值:

CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN [ICP].[UnitCost] * SUM(Sum([PL].[OriginalQuantity_Stk])  / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode] )
WHEN [PC].[ProductCategoryCode] = 5730 THEN ([ICP].[UnitCost] - 0.25) * SUM(Sum([PL].[OriginalQuantity_Stk])  / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode] )
WHEN [PC].[ProductCategoryCode] = 5990 THEN ([ICP].[UnitCost] * 0 ) * SUM(Sum([PL].[OriginalQuantity_Stk])  / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode] )
ELSE [ICP].[UnitCost] * SUM(Sum([PL].[OriginalQuantity_Stk])  / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode] )
END

ELSEpart 与我在报告的这一部分所需的产品代码相关。

我尝试使用两个不同的公式,它们都返回不同的金额,但不是正确的金额。

一个是:

CASE WHEN [PC].[ProductCategoryCode] = 5780 OR [PC].[ProductCategoryCode] < 5700 THEN SUM(Sum([PL].[OriginalQuantity_Stk])  / @Credits * [ICP].[UnitCost] )
OVER ()
END

另一个是:

SUM(Sum([PL].[OriginalQuantity_Stk])  / @Credits * [ICP].[UnitCost]) OVER
       (PARTITION BY (CASE WHEN [PC].[ProductCategoryCode] IN (5870, 5730, 5990)
                           THEN [PC].[ProductCategoryCode] 
                           END) 
       )  

他们通过为每个产品代码显示相同的数字来正确地对产品代码进行分组,但计算出来的数字不正确。

样本输出:

    Product Category Code | Value  |
    5870                  | 100    |
    5730                  | 400    |
    5990                  | 200    |
    5780                  | 200    |
    1111                  | 50     |  
    2222                  | 175    |  
    3333                  | 500    |  
    4444                  | 125    |  

    Total Value: 1050 
It has to ignore product code 5870, 5990, and 5730 and not include 
those in the total value.

我使用的是 Microsoft SQL Sever 2005。 如果我需要进一步解释,请告诉我。

完整代码:

SET NOCOUNT ON; 
DECLARE @Credits Decimal(19,8);
DECLARE @Price Decimal(19,8);

SET @Credits = 41000;
SET @Price = 1.57;

SELECT 
     CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN 'Trimmings' 
WHEN [PC].[ProductCategoryCode] = 5730 THEN 'Rib Tips'
WHEN [PC].[ProductCategoryCode] = 5990 THEN 'Skins'
ELSE [PC].[Description1] 
END AS [Description]
   , SUM(SUM(PL.OriginalQuantity_Stk)) OVER
 (PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
 THEN PC.ProductCategoryCode
 END)
) AS [Total Weight]
   , Sum(CASE WHEN [PC].[ProductCategoryCode] <> 5870 THEN [PL].[OriginalQuantity_Stk] 
WHEN [PC].[ProductCategoryCode] <> 5730 THEN [PL].[OriginalQuantity_Stk] 
WHEN [PC].[ProductCategoryCode] <> 5990 THEN [PL].[OriginalQuantity_Stk] 
END) AS [Weight]
   , @Credits - SUM(Sum([PL].[OriginalQuantity_Stk])) OVER () AS [Shrink]
   , CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode]) 
WHEN [PC].[ProductCategoryCode] = 5730 THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
WHEN [PC].[ProductCategoryCode] = 5990 THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
ELSE Sum([PL].[OriginalQuantity_Stk]) / @Credits
END AS [Yield]
   , CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN [ICP].[UnitCost] 
WHEN [PC].[ProductCategoryCode] = 5730 THEN [ICP].[UnitCost] - 0.25 
WHEN [PC].[ProductCategoryCode] = 5990 THEN [ICP].[UnitCost] * 0 
ELSE [ICP].[UnitCost]
END AS [UC]
   , CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN [ICP].[UnitCost] * SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
WHEN [PC].[ProductCategoryCode] = 5730 THEN ([ICP].[UnitCost] - 0.25) * SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
WHEN [PC].[ProductCategoryCode] = 5990 THEN ([ICP].[UnitCost] * 0) * SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
ELSE [ICP].[UnitCost] * SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
END AS [Value]
   , 
 **SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits * [ICP].[UnitCost]) OVER
 (PARTITION BY (CASE WHEN [PC].[ProductCategoryCode] IN (5870, 5730, 5990)
 THEN [PC].[ProductCategoryCode] 
                         END) 
) AS [TotalValue]**
 FROM (((( IC_Products [PC] 
    INNER JOIN  DC_Transactions [DCT] 
     ON [PC].ProductKey = [DCT].ProductKey)
    INNER JOIN  AR_Customers [ARC] 
     ON [DCT].CustomerKey = [ARC].CustomerKey)
    INNER JOIN  IC_ProductLots [PL] 
     ON [DCT].LotKey = [PL].LotKey)
    LEFT OUTER JOIN  IC_ProductCosts [ICP] 
     ON ICP.ProductKey=PC.ProductKey and ICP.ProductCostCode=5)
 WHERE 
    ([PL].ProductionDate >= { ts '2015-07-10 00:00:00' }   AND ([PL].ProductionDate <= { ts '2015-07-10 00:00:00' } OR [PL].ProductionDate Is Null)) 
AND ((1=1)  AND [ARC].CustomerKey IN (39) ) 
 GROUP BY 
     CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN 'Trimmings' 
WHEN [PC].[ProductCategoryCode] = 5730 THEN 'Rib Tips'
WHEN [PC].[ProductCategoryCode] = 5990 THEN 'Skins'
ELSE [PC].[Description1] 
END
   , [ARC].CustomerKey
   , [PC].ProductCategoryCode
   , CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN [ICP].[UnitCost] 
WHEN [PC].[ProductCategoryCode] = 5730 THEN [ICP].[UnitCost] - 0.25 
WHEN [PC].[ProductCategoryCode] = 5990 THEN [ICP].[UnitCost] * 0 
ELSE [ICP].[UnitCost]
END
   , [ICP].UnitCost
   , [PC].ProcessCode
 ORDER BY 
     @Credits - SUM(Sum([PL].[OriginalQuantity_Stk])) OVER () 
   , SUM(SUM(PL.OriginalQuantity_Stk)) OVER
 (PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
 THEN PC.ProductCategoryCode
 END)
)

*我需要帮助的部分代码。

【问题讨论】:

    标签: sql sql-server-2005 case window-functions cumulative-sum


    【解决方案1】:

    我不确定其他所有情况,但对于案例陈述,我认为这应该适合你

    SUM(CASE WHEN [PC].[ProductCategoryCode] = 5780 OR [PC].[ProductCategoryCode] < 5700 THEN [PL].[OriginalQuantity_Stk] ELSE 0 END) / @Credits * [ICP].[UnitCost] 
    

    【讨论】:

    • 我收到错误消息“无法对包含聚合或子查询的表达式执行聚合函数。”
    • @Austin 我想我已经修好了,如果没有,我会删除这个答案
    • 这在某种意义上是可行的,但它仍然不会创建一个总计值以保存为 [Total Value]。
    • @Austin 总计是假设是最后一行还是另一列?如果您希望它作为最后一行,您可以将其创建到 CTE 中,并添加一个带有每列总和的并集来总计它们。
    • 我只是将它作为另一列并将该列作为标题(使用我使用的 DBMS)
    猜你喜欢
    • 2015-04-24
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    相关资源
    最近更新 更多