我需要计算特定范围的产品代码的总价值。我需要进行计算的产品代码是5780,一切都在5700以下。
要获得总价值,我需要这些产品的总成本以及产量。
Value = Pirce * Yield %
为了计算产量,我使用等式:
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
价格已经在系统中,所以我不需要计算。
我已经尝试了几个方程来计算总值,但没有一个能够返回所需的数量。
我觉得它应该类似于这个等式,但这只是显示每行的值而不是一个总值:
SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits) OVER (
PARTITION BY (
CASE
WHEN PC.ProductCategoryCode = 5780
OR [PC].[ProductCategoryCode] < 5700
THEN PC.ProductCategoryCode
END
)
) * ICP.UnitCost
此等式显示一个总和,但总数不正确:
CASE
WHEN [PC].[ProductCategoryCode] = 5780 OR [PC].[ProductCategoryCode] < 5700
THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / @Credits * [ICP].[UnitCost]) OVER ()
END
我想也许我也需要UnitCost的SUM,但当我尝试在等式中做到这一点时,我会收到错误。
样本表:
Credits 375.00
Product Code| Weight | Yield |Unit Cost| Value
Pizza | 150.00 | 40.00% | $2.25 | 0.900000
Potato Chips| 25.00 | 6.60% | $1.00 | 0.06600
Hot Dog | 125.00 | 33.00% | $2.00 | 0.66000
Soda | 50.00 | 13.00% | $1.50 | 0.195000
-------------------------------------------------------------
Total | 350.00 | | 1.821000
Total Value = 1.821000
另一个示例解释了我只想要某些产品代码:
Product Category Code | Value |
----------------------x--------x
5870 | 100 |
5730 | 400 |
5990 | 200 |
5780 | 200 |
1111 | 50 |
2222 | 175 |
3333 | 500 |
4444 | 125 |
总价值:1050 它必须忽略产品代码5870,5990和5730而不包括 那些总价值。
我正在使用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) OVER (
PARTITION BY (
CASE
WHEN PC.ProductCategoryCode = 5780
OR [PC].[ProductCategoryCode] < 5700
THEN PC.ProductCategoryCode
END
)
) * ICP.UnitCost 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 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
)
)
答案 0 :(得分:1)
好吧,这可能无法按照您想要的方式运作。但是,我试图清理你的代码花了很多时间,但据我所知,你可能甚至不需要窗口版本的SUM
函数。 Note: the query below may not properly compile as I do not have exact sample data to test this sample code.
SET NOCOUNT ON;
DECLARE @Credits DECIMAL(19, 8);
DECLARE @Price DECIMAL(19, 8);
SET @Credits = 41000;
SET @Price = 1.57;
BEGIN
SELECT q1.[Description],
q1.[Total Weight],
q1.Shrink,
q1.Yield,
q1.UC,
sum(q1.[Value]) AS [Total_Value]
FROM
(
--Product codes 5870 and less than 5700
SELECT
PC.Description1 AS [Description]
,SUM(PL.OriginalQuantity_Stk) AS [Total Weight]
--,Sum(PL.OriginalQuantity_Stk) AS [Weight]
,@Credits - Sum(PL.OriginalQuantity_Stk) AS [Shrink]
,(Sum(PL.OriginalQuantity_Stk) / @Credits) AS [Yield]
,ICP.UnitCost AS [UC]
,ICP.UnitCost * (Sum(PL.OriginalQuantity_Stk) / @Credits) AS [Value]
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 JOIN IC_ProductCosts ICP ON ICP.ProductKey = PC.ProductKey
AND ICP.ProductCostCode = 5
WHERE ((PL.ProductionDate >= '2015-07-10 00:00:00' AND PL.ProductionDate <= '2015-07-10 00:00:00') OR PL.ProductionDate IS NULL)
AND ARC.CustomerKey = 39
AND (PC.ProductCategoryCode = 5780 OR PC.ProductCategoryCode < 5700) --add this check in your where clause to limit to product codes you are interested in
GROUP BY
PC.Description1
,ARC.CustomerKey
,PC.ProductCategoryCode
,ICP.UnitCost
,PL.ProductionDate
UNION ALL
--Other Product codes
SELECT
PC.Description1 AS [Description]
,SUM(PL.OriginalQuantity_Stk) AS [Total Weight]
--,Sum(PL.OriginalQuantity_Stk) AS [Weight]
,@Credits - Sum(PL.OriginalQuantity_Stk) AS [Shrink]
,(Sum(PL.OriginalQuantity_Stk) / @Credits) AS [Yield]
,ICP.UnitCost AS [UC]
,ICP.UnitCost * (Sum(PL.OriginalQuantity_Stk) / @Credits) AS [Value]
,(Sum(PL.OriginalQuantity_Stk) / @Credits)* ICP.UnitCost 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 JOIN IC_ProductCosts ICP ON ICP.ProductKey = PC.ProductKey
AND ICP.ProductCostCode = 5
WHERE ((PL.ProductionDate >= '2015-07-10 00:00:00' AND PL.ProductionDate <= '2015-07-10 00:00:00') OR PL.ProductionDate IS NULL)
AND ARC.CustomerKey = 39
AND (PC.ProductCategoryCode <> 5780 OR PC.ProductCategoryCode > 5700) --add this check in your where clause to limit to product codes you are interested in
GROUP BY
PC.Description1
,ARC.CustomerKey
,PC.ProductCategoryCode
,ICP.UnitCost
,PL.ProductionDate
) AS q1
GROUP BY q1.[Description],
q1.[Total Weight],
q1.Shrink,
q1.Yield,
q1.UC
END
答案 1 :(得分:0)
也许这就是你所追求的:
SELECT otherColumns,
SUM(
CASE WHEN ProductCategoryCode < 5700 OR ProductCategoryCode=5780
THEN OriginalQuantity_Stk
ELSE 0
END
) OVER () / @credits * UnitCost AS tova
FROM JoinedTables -- WHERE ...
CASE
子句需要完全包含在SUM()
聚合函数中,然后将结果除以@credits
并在之后乘以UnitCost
> OVER ()
条款。
由于您最初发布的查询有点笨拙,我创建了一个小sqlfiddle只有几列,可以演示我的查询版本基本如何工作(列UnitCost
包含我做的任意值向上)。