SQL组合方程时总计不正确

时间:2015-07-14 17:34:14

标签: sql-server variables aggregate-functions

对于我正在创建的报告,我需要采用两个单独的表达式并将它们组合起来以获得一个解决方案。

我需要的第一个表达式是Total Sales,它由

计算
Sum([DCT].[Quantity_Stk] *[ICP].[UnitCost]) AS [Total Sales]

我需要的第二个表达式是Total Cost,它由

计算
 Max(CAST ((@PurchaseCost + @Prod_CostLBS) * @InputWeight AS DECIMAL (18,2))) AS [Cost]

这两个语句都有效,因为它们用于查询中的其他列并正确显示。

为了找出总利润我尝试使用SUM, AVG, MAX and by trying to make it an expression but that results in an error.将两者结合起来我相信下面的代码有正确的想法,它只是缺少一些重要的部分。也许是OVER()陈述:

CAST (([DCT].[Quantity_Stk] *[ICP].[UnitCost]) - ((@PurchaseCost + @Prod_CostLBS) * @InputWeight) AS DECIMAL(18,2)) AS [Profit]

我遇到的问题是它正在计算每一行的利润,但我只想要总利润。哪个会使它成为我相信的聚合函数。或者有没有办法将其他两个表达式存储为变量并使用它们?

我使用的是Microsoft SQL Server 2005。

完整代码:

SET NOCOUNT ON; 
DECLARE @PurchaseCost Decimal(19,8);
DECLARE @InputWeight Decimal(19,8);
DECLARE @Prod_CostLBS Decimal(19,8);

SET @PurchaseCost = 2.58;
SET @InputWeight = 18100;
SET @Prod_CostLBS  = .15;

SELECT 
     CAST([ARC].[CustomerCode] AS NVARCHAR(40)) + ' - ' + CAST([ARC].[Name] AS NVARCHAR(40)) AS [Supplier]
   , [PC].ProductCode
   , [PC].Description1
   , Count(IC_ProductLots.OriginalQuantity_Alt) AS [Boxes]
   , IC_ProductLots.UnitOfMeasure_Alt
   , Sum(IC_ProductLots.OriginalQuantity_Stk) AS [Weight]
   , IC_ProductLots.UnitOfMeasure_Stk
   , [ICP].UnitCost AS [Unit Cost]
   , Sum([DCT].[Quantity_Stk] *[ICP].[UnitCost]) AS [Total Sales]
   , Avg(([IC_ProductLots].[OriginalQuantity_Stk] / [IC_ProductLots].[OriginalQuantity_Alt])) AS [Avg. Box Weight]
   , Sum([IC_ProductLots].[OriginalQuantity_Stk] / @InputWeight) AS [Yield]
   , CAST (@InputWeight - SUM(Sum([IC_ProductLots].[OriginalQuantity_Stk])) OVER () AS DECIMAL(18,2)) AS [Shrink]
   , Max(CAST ((@PurchaseCost + @Prod_CostLBS) * @InputWeight AS DECIMAL (18,2))) AS [Cost]
   , Max(CAST (([DCT].[Quantity_Stk] *[ICP].[UnitCost]) - ((@PurchaseCost + @Prod_CostLBS) * @InputWeight) AS DECIMAL(18,2))) AS [Profit]
 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 
     ON [DCT].LotKey = IC_ProductLots.LotKey)
    LEFT OUTER JOIN  IC_ProductCosts [ICP] 
     ON ICP.ProductKey=PC.ProductKey and ICP.ProductCostCode=5)
 WHERE 
    (IC_ProductLots.ProductionDate >= { ts '2015-06-24 00:00:00' }   AND (IC_ProductLots.ProductionDate <= { ts '2015-06-24 00:00:00' } OR IC_ProductLots.ProductionDate Is Null)) 
AND ((1=1)  AND [ARC].CustomerKey IN (124) ) 
 GROUP BY 
     CAST([ARC].[CustomerCode] AS NVARCHAR(40)) + ' - ' + CAST([ARC].[Name] AS NVARCHAR(40))
   , [PC].ProductCode
   , [PC].Description1
   , IC_ProductLots.UnitOfMeasure_Alt
   , IC_ProductLots.UnitOfMeasure_Stk
   , [ICP].UnitCost
   , IC_ProductLots.ProductionDate
   , [ARC].CustomerKey
 ORDER BY 
     CAST([ARC].[CustomerCode] AS NVARCHAR(40)) + ' - ' + CAST([ARC].[Name] AS NVARCHAR(40)) 
   , CAST (@InputWeight - SUM(Sum([IC_ProductLots].[OriginalQuantity_Stk])) OVER () AS DECIMAL(18,2)) 
   , Max(CAST ((@PurchaseCost + @Prod_CostLBS) * @InputWeight AS DECIMAL (18,2))) 
   , Max(CAST (([DCT].[Quantity_Stk] *[ICP].[UnitCost]) - ((@PurchaseCost + @Prod_CostLBS) * @InputWeight) AS DECIMAL(18,2)))

临时表

所以我会创建一个类似于

的表达式
SELECT Sum([DCT].[Quantity_Stk] *[ICP].[UnitCost]) as Total Sales 
INTO #TempTable 
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 ON [DCT].LotKey = IC_ProductLots.LotKey) LEFT OUTER JOIN IC_ProductCosts [ICP] ON ICP.ProductKey=PC.ProductKey and ICP.ProductCostCode=5)
GROUP BY unitcost

1 个答案:

答案 0 :(得分:0)

声明你的变量:

SET NOCOUNT ON; 
DECLARE @PurchaseCost Decimal(19,8);
DECLARE @InputWeight Decimal(19,8);
DECLARE @Prod_CostLBS Decimal(19,8);

SET @PurchaseCost = 2.58;
SET @InputWeight = 18100;
SET @Prod_CostLBS  = .15;

将所有原始数据放入如下的临时表中:

    SELECT 
         CAST([ARC].[CustomerCode] AS NVARCHAR(40)) + ' - ' + CAST([ARC].[Name] AS NVARCHAR(40)) AS [Supplier]
       , [PC].ProductCode
       , [PC].Description1
       , IC_ProductLots.OriginalQuantity_Alt AS [Boxes]
       , IC_ProductLots.UnitOfMeasure_Alt
       , IC_ProductLots.OriginalQuantity_Stk AS [Weight]
       , IC_ProductLots.UnitOfMeasure_Stk
       , [ICP].UnitCost AS [Unit Cost]
       , [DCT].[Quantity_Stk] * [ICP].[UnitCost] AS [Total Sales]
       , ([IC_ProductLots].[OriginalQuantity_Stk] / [IC_ProductLots].[OriginalQuantity_Alt]) AS [Avg. Box Weight] --not sure about this one
       , [IC_ProductLots].[OriginalQuantity_Stk] / @InputWeight AS [Yield]
       , CAST([IC_ProductLots].[OriginalQuantity_Stk] AS DECIMAL(18,2)) AS [Shrink]
       , CAST ((@PurchaseCost + @Prod_CostLBS) * @InputWeight AS DECIMAL (18,2)) AS [Cost]
       , CAST (([DCT].[Quantity_Stk] *[ICP].[UnitCost]) - ((@PurchaseCost + @Prod_CostLBS) * @InputWeight) AS DECIMAL(18,2)) AS [Profit]
  INTO #TempTable
     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 
         ON [DCT].LotKey = IC_ProductLots.LotKey)
        LEFT OUTER JOIN  IC_ProductCosts [ICP] 
         ON ICP.ProductKey=PC.ProductKey and ICP.ProductCostCode=5)
     WHERE 
        (IC_ProductLots.ProductionDate >= { ts '2015-06-24 00:00:00' }   AND (IC_ProductLots.ProductionDate <= { ts '2015-06-24 00:00:00' } OR IC_ProductLots.ProductionDate Is Null)) 
    AND ((1=1)  AND [ARC].CustomerKey IN (124) ) 

然后将聚合设置为要在select语句中使用的变量:

DECLARE @TotalSales decimal(19,8) = (SELECT Sum([Total Sales]) FROM #TempTable
DECLARE @TotalProfit decimal(19,8) = (SELECT SUM([Profit]) FROM #TempTable
DECLARE @TotalCost decimal(19,8) = (SELECT SUM([Cost]) FROM #TempTable

SELECT
[FieldNames]
[Aggregates]
FROM #TempTable
GROUP BY [Any field not included in the aggregates]