2010-04-07 7 views
5

J'ai 2 tables AP et INV où les deux ont les colonnes [PROJECT] et [Value].données de somme sql de plusieurs tables

Je veux une requête pour renvoyer quelque chose comme ceci:

PROJET | SUM_AP | SUM_INV

Je suis venu avec le code ci-dessous, mais il retourne les mauvais résultats (somme est erronée).

SELECT AP.[PROJECT], 
SUM(AP.Value) AS SUM_AP, 
SUM(INV.Value) AS SUM_INV 
FROM AP INNER JOIN INV ON (AP.[PROJECT] =INV.[PROJECT]) 
WHERE AP.[PROJECT] = 'XXXXX' 
GROUP BY AP.[PROJECT] 

Répondre

11

Les résultats de votre requête sont erronés car les valeurs que vous essayez de récapituler sont groupées, ce qui entraîne l'inclusion de valeurs en double dans le SUM.

Vous pouvez le résoudre avec deux sous-Selects:

SELECT 
    AP1.[PROJECT], 
    (SELECT SUM(AP2.Value) FROM AP AS AP2 WHERE AP2.PROJECT = AP1.PROJECT) AS SUM_AP, 
    (SELECT SUM(INV2.Value) FROM INV AS INV2 WHERE INV2.PROJECT = AP1.PROJECT) AS SUM_INV 
FROM AP AS AP1 
    INNER JOIN INV AS INV1 
     ON (AP1.[PROJECT] =INV1.[PROJECT]) 
WHERE AP1.[PROJECT] = 'XXXXX' 
GROUP BY AP1.[PROJECT] 
+0

je reçois « Vous avez essayé d'exécuter une requête qui ne comprend pas l'expression spécifiée « projet » dans le cadre de une fonction agrégée. " – Iulian

+0

J'ai mis à jour la deuxième sous-requête pour éviter une autre colonne de regroupement. Pourriez-vous réessayer? – Prutswonder

+0

cela fonctionne bien maintenant, renvoyant les résultats corrects, merci – Iulian

2

Si vous avez N lignes AP avec un ID de projet donné, et M lignes INV avec cet ID, la jointure entre les deux tables sur l'ID du projet aura un total de N*M lignes pour ce projet , parce que la même ligne dans AP sera répétée pour chaque ligne dans INV qui a cet ID de projet, et vice versa. C'est pourquoi vos comptes sont très probablement désactivés (car il compte plusieurs fois la même ligne dans un tableau en raison de la répétition de la jointure). Au lieu de cela, vous pouvez essayer de faire une jointure entre les résultats de deux sous-requêtes, une qui regroupe la première table par ID de projet et fait sa somme, et la seconde qui regroupe l'autre table par ID de projet. somme - puis rejoindre une fois que vous avez seulement 1 ligne avec somme pour chaque ID de projet.

-1

Essayez:

SELECT AP.[PROJECT] AS PROJECT, SUM(AP.[Value]) AS SUM_AP, SUM(INV.[Value]) AS SUM_INV 
FROM AP, INV 
WHERE AP.[PROJECT] = INV.[PROJECT] 
AND AP.[PROJECT] = 'XXXXX' 
GROUP BY AP.[PROJECT] 
+0

cela renvoie les mêmes mauvais résultats que le mien :( – Iulian

0

Si le projet est la table parent, vous devez sélectionner à partir de la table de projet, et faire un jointure externe gauche sur les deux tables enfant:

SELECT PROJECT.PROJECT_ID, SUM(AP.Value) AS SUM_AP, SUM(INV.Value) AS SUM_INV 
FROM PROJECT 
LEFT OUTER JOIN AP ON (AP.[PROJECT] = PROJECT.[PROJECT_ID]) 
LEFT OUTER JOIN INV ON (INV.[PROJECT] = PROJECT.[PROJECT_ID]) 
WHERE PROJECT.[PROJECT_ID] = 'XXXXX' 
GROUP BY PROJECT.[PROJECT_ID] 
0

Vous pouvez séparer les deux calculs de somme. Une façon je peux penser est de déplacer le calcul des stocks à un sous-requête, comme:

SELECT 
    AP.[PROJECT] 
, SUM(AP.Value) AS SUM_AP 
, SummedInv as SUM_INV 
FROM AP 
LEFT JOIN (
    SELECT PROJECT, SUM(Value) AS SUM_INV 
    FROM INV 
    GROUP BY PROJECT 
) SummedInv ON SummedInv.Project = AP.Project 
GROUP BY AP.PROJECT, SummedInv.SUM_INV 

Parce que la sous-requête SummedInv est regroupée sur project, il est sûr de groupe sur SummedInv.SUM_INV dans la requête externe aussi bien.

0

comment au sujet de cette requête:

select SUM(gpCutBody.actualQty) as cutQty , SUM(gpSewBody.quantity) as sewQty 

from jobOrder 
inner join gpCutHead on gpCutHead.joNum = jobOrder.joNum 
inner join gpSewHead on gpSewHead.joNum = jobOrder.joNum 

inner join gpCutBody on gpCutBody.gpCutID = gpCutHead.gpCutID 
inner join gpSewBody on gpSewBody.gpSewID = gpSewHead.gpSewID 


where jobOrder.joNum = '36' 

est ici le lien vers la DRE: http://dl.dropbox.com/u/18794525/AUG%207%20DUMP%20STAN.png

+0

Etes-vous posté un ERD de votre DB? Je pense qu'il est préférable de répondre à l'info que le PO fournir –

Questions connexes