2010-06-27 4 views
0

Nous avons le code SQL suivant que nous utilisons pour calculer les coûts totaux. Comme il va de soi, nous recueillons des données à partir de deux tables différentes pour calculer le coût total de production pour chaque client.mise à jour d'une somme d'une table basée sur l'entrée d'une autre table

Nous avons maintenant besoin d'ajouter une autre table à ce mélange. Ce nouveau tableau identifie la remise qui s'applique à chaque ressource par client. De plus, plusieurs lignes peuvent faire référence au même client et à la même ressource. Dans ce cas, toutes les réductions doivent être additionnées pour identifier la remise totale.

Par exemple:

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

Donc, nous devons identifier la remise totale par client pour chaque ressource (ce qui est assez facile à faire pour moi). Et puis utilisez cette réduction dans le SQL ci-dessus et déduisez-le de CostPerUnit pour cette ressource particulière lors du calcul de la colonne TotalCost (j'espère que cela a du sens). J'ai essayé toutes sortes de jointures et j'espère que quelqu'un ici pourra m'aider avec ça. Toute aide est très appréciée.

Merci!

Répondre

2

Dans cette solution, j'utilise une nouvelle fonctionnalité introduite dans SQL Server 2005 qui est l'opérateur OUTER APPLY. Cela vous permet de référencer des colonnes dans les tables externes. J'utilise OUTER APPLY au lieu de CROSS APPLY pour tenir compte de la possibilité qu'il n'y a pas de lignes de remise.

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 

Une autre approche serait d'utiliser une table dérivée:

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

Thomas, qui était vraiment rapide! Merci beaucoup. Je vais donner un coup de feu. – Azeem

+0

Thomas, merci beaucoup. Cela a très bien fonctionné. J'ai dû modifier un peu l'utilisation de Discount.Total pour ne pas avoir d'erreurs sur le fait que cela ne soit pas inclus dans la clause GROUP BY ou ne soit pas une somme. Mais les deux requêtes ont parfaitement fonctionné. Merci encore. – Azeem

1

Une autre approche

;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

Merci Chris. Je garderai cela à l'esprit pour un usage futur. :) – Azeem

Questions connexes