2010-06-27 6 views
0

У нас есть следующий 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 выше и вычтите ее из CostPerUnit для этого конкретного ресурса при расчете столбца TotalCost (надеюсь, это имеет смысл). Я пробовал всевозможные объединения, и я надеюсь, что кто-то здесь поможет мне в этом. Буду признателен за любую оказанную помощь.

Спасибо!

ответ

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 
+0

Томас, это было очень быстро! Большое спасибо. Я сделаю снимок. – Azeem

+0

Томас, большое спасибо. Это работало очень хорошо. Мне пришлось изменить использование Discount.Total немного, поэтому я не буду получать ошибки о том, что не входит в предложение GROUP BY или не является суммированием. Но оба запроса отлично работали. Еще раз спасибо. – Azeem

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 
+0

Спасибо, Крис. Я буду помнить об этом в будущем. :) – Azeem

Смежные вопросы