problème d'agrégation mssql avec le niveau de jointure et parent-enfant

Les exemples de la table source

Table1 id id_parent product_id === ========= ======== 154 104389 1043891 155 104389 1995137331 

alors j'ai deux autres tables d'inventaire comme ci-dessous:

 (table2) product_id location_id on_hand transit 1043891 2 12 1 1043891 5 33 0 1043891 6 7 0 1043891 4 3 0 1995137331 2 8 5 1995137331 8 50 9 1995137331 5 95 0 1995137331 11 22 5 1995137331 13 93 1 (table3) product_id location_id on_hand transit 1043891 1 25 1 1995137331 1 29 0 

J'ai cette requête suivante:

 ; with O as (select Product_Id, SUM(OnHand) AS AllStore from Table2 group by Product_Id), S as (select Product_Id, SUM(OnHand) as WH from Table3 group by Product_Id) SELECT L1.id_parent as parent ,L1.product_id as child , O.AllStore , S.WH FROM Table1 L0 JOIN Table1 L1 ON L0.id_parent = L1.id_parent LEFT OUTER JOIN S on S.Product_ID = L0.Product_Id LEFT OUTER JOIN O on O.Product_ID = L0.Product_ID group by L1.id_parent, L1.product_id, S.WH, O.AllStore 

Cela marche un peu, mais en dupliquant les loggings. résultat actuel:

 parent child AllStore WH 1043892 1043891 104 102 1043892 1043891 242 123 1043892 1995137331 104 102 1043892 1995137331 242 123 

Résultat attendu:

 parent child AllStore WH 1043892 1043891 104 102 1043892 1995137331 242 123 

Quelqu'un peut-il regarder s'il vous plaît et voir ce que je fais mal ou s'il y a une meilleure façon de le faire.

Merci.

Les problèmes viennent en raison de votre jointure de Table1 sur lui-même avec la condition de

 L0.id_parent = L1.id_parent 

Cette jointure prend efficacement la table 1 avec 2 rangées de 104389 et se joint sur elle-même avec les 2 rangées. Cette condition de jointure produira 4 lignes.

 SELECT * FROM @Table1 L0 INNER JOIN @Table1 L1 ON L0.id_parent = L1.id_parent id id_parent product_id id id_parent product_id ----------- ----------- ----------- ----------- ----------- ----------- 154 104389 1043891 154 104389 1043891 154 104389 1043891 155 104389 1995137331 155 104389 1995137331 154 104389 1043891 155 104389 1995137331 155 104389 1995137331 

A partir des exemples que vous avez donnés, cette jointure est totalement inutile car datatables dont vous avez besoin sont déjà dans L0

L'instruction group by est également inutile car vous n'exécutez aucun agrégat. le résultat final de l'avoir laissé est le même que de mettre un DISTINCT sur la requête globale.

Par conséquent: pour produire les "résultats attendus" décrits, la requête peut être modifiée à la suivante

 ; with O as (select Product_Id, SUM(on_hand) AS AllStore from @Table2 group by Product_Id), S as (select Product_Id, SUM(on_hand) as WH from @Table3 group by Product_Id) SELECT L0.id_parent as parent ,L0.product_id as child ,O.AllStore ,S.WH FROM @Table1 L0 LEFT OUTER JOIN S ON S.Product_ID = L0.Product_Id LEFT OUTER JOIN O ON O.Product_ID = L0.Product_ID 

Note: Si la jointure L0 et L1 est une faute de frappe, et qu'il y a une 4ème table en jeu mais produisant toujours des duplicates, vous pouvez extraire les jointures L0 et L1 dans une sous-requête et la DISTINCTER.