根据另一个表的输入更新一个表的总和

时间:2010-06-27 04:25:07

标签: sql tsql sql-server-2008

我们使用以下SQL来计算总成本。

 SELECT 
    DailyProduction.CustomerId as CustomerId, 
    SUM(Resource.CostPerUnit * DailyProduction.UnitsToStorage + Resource.CostPerUnit * DailyProduction.UnitsToMarket) AS TotalCost
 FROM 
    dbo.hgm_ResourceTypes Resource
 JOIN
    dbo.hgm_ResourceDailyProduction DailyProduction
 ON
    Resource.ResourceId = DailyProduction.ResourceId
 GROUP BY
    DailyProduction.CustomerId

很明显,我们从两个不同的表中收集数据,以计算每个客户的总生产成本。

我们现在需要在此混音中添加另一个表格。此新表标识了适用于每个客户的每个资源的折扣。此外,多行可以指代相同的客户和相同的资源。在这种情况下,所有折扣必须加在一起以确定总折扣。

例如:

CUSTOMER: 1  RESOURCE: 1   DISCOUNT: 1
CUSTOMER: 1  RESOURCE: 1   DISCOUNT: 3
CUSTOMER: 1  RESOURCE: 2   DISCOUNT: 5

因此,我们必须确定每个资源的每个客户的总折扣(这对我来说相当容易)。然后在上面的SQL中使用该折扣,并在计算TotalCost列时从该特定资源的CostPerUnit中扣除它(希望这是有意义的)。我一直在尝试各种各样的连接,我希望有人可以帮助我。任何帮助深表感谢。

谢谢!

2 个答案:

答案 0 :(得分:2)

在此解决方案中,我使用的是SQL Server 2005中引入的新功能,即OUTER APPLY运算符。这允许您引用外部表中的列。我使用OUTER APPLY而不是CROSS APPLY来说明没有折扣行的可能性。

Select  DailyProduction.CustomerId as CustomerId
    ,  SUM(Resource.CostPerUnit * DailyProduction.UnitsToStorage 
        + Resource.CostPerUnit * DailyProduction.UnitsToMarket) AS TotalCost
    , Coalesce(Discount.Total, 0) As TotalDiscount
 From  dbo.hgm_ResourceTypes As Resource
    Join dbo.hgm_ResourceDailyProduction As DailyProduction
        On Resource.ResourceId = DailyProduction.ResourceId
    Outer Apply (
                Select Sum(D1.Discount) As Total
                From dbo.hgm_Discounts As D1
                Where D1.CustomerId = DailyProduction.CustomerId
                    And D1.ResourceId = Resource.ResourceId
                ) As Discount
 Group By DailyProduction.CustomerId

另一种方法是使用派生表:

 Select  DailyProduction.CustomerId as CustomerId
    ,  SUM(Resource.CostPerUnit * DailyProduction.UnitsToStorage 
        + Resource.CostPerUnit * DailyProduction.UnitsToMarket) AS TotalCost
    , Coalesce(Discount.Total, 0) As TotalDiscount
 From  dbo.hgm_ResourceTypes As Resource
    Join dbo.hgm_ResourceDailyProduction As DailyProduction
        On Resource.ResourceId = DailyProduction.ResourceId
    Left Join   (
                Select D1.CustomerId, D1.ResourceId, Sum(D1.Discount) As Total
                From dbo.hgm_Discounts As D1
                Group By D1.CustomerId, D1.ResourceId
                ) As Discount
        On Discount.CustomerId = DailyProduction.CustomerId
            And Discount.ResourceId = Resource.ResourceId
 Group By DailyProduction.CustomerId

答案 1 :(得分:1)

另一种方法

;WITH Discounts AS
(
  SELECT ResourceID, CustomerID, SUM(Discounts) AS TotalDiscount
  FROM dbo.hgm_Discounts
  GROUP BY ResourceID, CustomerID
)
SELECT DailyProduction.CustomerId as CustomerId,
  SUM((Resource.CostPerUnit - COALESCE(Discounts.TotalDiscount ,0)) * DailyProduction.UnitsToStorage
     + (Resource.CostPerUnit - COALESCE(Discounts.TotalDiscount ,0)) * DailyProduction.UnitsToMarket) AS TotalCost
FROM dbo.hgm_ResourceTypes Resource 
INNER JOIN dbo.hgm_ResourceDailyProduction DailyProduction 
    ON Resource.ResourceId = DailyProduction.ResourceId 
LEFT OUTER JOIN Discounts
    ON Resource.ResourceId = Discounts.ResourceId
   AND DailyProduction.CustomerId = Discounts.CustomerId
GROUP BY
    DailyProduction.CustomerId