2013-01-10 1 views
0

J'ai une requête de vieillissement qui fait vieillir la quantité d'articles achetés et leurs coûts dans des intervalles de 12, 24 et 36 mois. La requête s'exécute très bien, mais mes totaux ne s'additionnent pas par rapport à une seule requête utilisée pour trouver le total pour un fournisseur particulier.Les totaux d'ancienneté de SQL Server ne correspondent pas

Voir ci-dessous.

SELECT s.SupplierNumber as Supplier_Number 
    , s.suppliername as Supplier_Name 
    , i.supplierpartnum as Part_No 
    , SUBSTRING(e.account_code,1,5)/*+'-'+RIGHT(e.account_code,7)*/ as Account_Code 
    , CASE WHEN e.reference_code = '' 
     THEN 'NOREF' 
     ELSE reference_code 
     END as Reference_Code 
    , i.Commodity 
    , i.ShortDscrptn as Part_Desc 
    , i.unitofmeasure as UOM 
    , i.unitprice as Unit_Price 
, CASE WHEN h.OrderDate >= '2012-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN COUNT(i.Quantity) 
     ELSE 0 END as Annual_Qty_12 
, CASE WHEN h.OrderDate >= '2011-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN COUNT(i.Quantity) 
     ELSE 0 END as Annual_Qty_24 
, CASE WHEN h.OrderDate >= '2010-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN COUNT(i.Quantity) 
     ELSE 0 END as Annual_Qty_36 
, CASE WHEN h.OrderDate >= '2012-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN SUM(i.UnitPrice) 
     ELSE 0 END as Annual_Spend_12   
, CASE WHEN h.OrderDate >= '2011-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN SUM(i.UnitPrice) 
     ELSE 0 END as Annual_Spend_24 
, CASE WHEN h.OrderDate >= '2010-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN SUM(i.UnitPrice) 
     ELSE 0 END as Annual_Spend_36 
FROM ekp.dbo.SUPPLIER s 
JOIN ekp.dbo.ORDERHEADER h 
    ON s.SupplierID = h.SupplierID 
JOIN ekp.dbo.ORDERITEM i 
    ON h.OrderID = i.OrderID 
JOIN mgnt.dbo.ematch e 
    ON h.PONumber = e.po_ctrl_num 
    AND i.LineNumber = e.po_sequence_id 
WHERE h.OrderDate >= '2010-01-01' 
AND h.OrderDate <= '2012-12-31' 
GROUP BY s.SupplierNumber, s.SupplierName, i.SupplierPartNum, e.account_code 
, i.Commodity, i.UnitOfMeasure, i.UnitPrice, i.ShortDscrptn, h.OrderDate 
, e.reference_code 

je peux aller de l'avant et de copier les résultats à une feuille de calcul et résumer la colonne Annual_Spend_12 pour un Supplier particulier et il ne correspond pas à ce qui suit:

SELECT SUM(i.unitprice) as Annual_Spend_12 
    FROM ekp.dbo.ORDERITEM i 
JOIN ekp.dbo.ORDERHEADER h 
    ON i.OrderID = h.OrderID 
JOIN ekp.dbo.Supplier s 
    ON h.SupplierID = s.SupplierID 
JOIN mgnt.dbo.ematch e 
    ON h.PONumber = e.po_ctrl_num 
    AND i.LineNumber = e.po_sequence_id 
WHERE s.SupplierNumber = '15302' 
AND h.OrderDate >= '2012-01-01' 
AND h.OrderDate <= '2012-12-31' 

Cette requête juste au-dessus les totaux toujours beaucoup, beaucoup plus élevé que la requête supérieure. J'ai aussi rÉsuMer et DISPOSONS l'agrégat entier au lieu et il ne correspond pas, en fait, il a également produit les mêmes résultats que la requête principale:

, COUNT(CASE WHEN h.OrderDate >= '2012-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN i.Quantity 
     ELSE 0 END) as Annual_Qty_12 
, COUNT(CASE WHEN h.OrderDate >= '2011-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN i.Quantity 
     ELSE 0 END) as Annual_Qty_24 
, COUNT(CASE WHEN h.OrderDate >= '2010-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN i.Quantity 
     ELSE 0 END) as Annual_Qty_36 
, SUM(CASE WHEN h.OrderDate >= '2012-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN i.UnitPrice 
     ELSE 0 END) as Annual_Spend_12   
, SUM(CASE WHEN h.OrderDate >= '2011-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN i.UnitPrice 
     ELSE 0 END) as Annual_Spend_24 
, SUM(CASE WHEN h.OrderDate >= '2010-01-01' 
     AND h.OrderDate <= '2012-12-31' 
     THEN i.UnitPrice 
     ELSE 0 END) as Annual_Spend_36 

Je redoutais à écrire sérieusement une procédure stockée avec des tables temporaires pour chaque agrégat.

Toute aide est appréciée.

+0

Pouvez-vous poster des exemples de données? Je peux voir plusieurs endroits qui pourraient le jeter, mais cela dépend vraiment de la nature de vos données ... – PinnyM

+0

Vous avez différentes profondeurs d'agrégation entre les requêtes. Supprimez tout de la sélection et du groupe par le haut à l'exception de SupplierNumber et voyez si cela totalise. –

+0

En outre, vous pouvez facilement modifier cela en SQL dynamique afin de ne pas avoir à coder les dates en dur et ne pas nécessiter de maintenance annuelle des sprocs. –

Répondre

0

Je suppose que le test est faux: vous additionnez les valeurs dans Excel incorrect pour la première requête. Voici trois façons valides d'additionner des valeurs dans Excel:

  • Filtrez les valeurs et mettez la colonne en surbrillance. Excel va ajouter les valeurs dans les cellules de sélection (Excel 2007 et supérieur).
  • utilisation « sumif() » ou « somme ({}) » pour ajouter les totaux pour un fournisseur donné
  • Utilisez un tableau croisé dynamique

Les résultats d'un group by sont pas nécessairement triés. Ils peuvent sembler triés, mais ils pourraient ne pas l'être. Une façon d'effectuer une agrégation consiste à trier les données, puis à sélectionner les résultats. Cependant, il existe d'autres méthodes, telles que l'agrégation de hachage. Et, dans un environnement multithread, vous ne savez pas quel thread va retourner les valeurs dans quel ordre.

Questions connexes