Aller au contenu

SQL Jointure sur 3 tables


Aloyse57

Messages recommandés

Salut,

Je ne sais pas si je suis fatigué mais je bute sur une jointure qui à la base me paraît simple.
J'ai préparé l'exemple (voir pièce jointe).

Il me semble qu'en 35 ans de prog j'ai fait ça des centaines de fois. J'ai tout à coup des sueurs en imaginant que toutes mes requêtes aient été fausses et que personne ne s'en soit jamais aperçu 😂.

J'en viens à me demander si c'est mon SQL-Server 2005 (oui je sais, mais on fait ce qu'on peut avec ce qu'on a) qui me joue des tours.

Voyez-vous ce que j'ai raté dans cette requête ?

Merci,

Snap1284.jpg

Lien vers le commentaire
Partager sur d’autres sites

Pas pratiquer depuis très très longtemps, mais pour moi il faut passer par des resuêtes imbriquées.

Ca donnerait un truc du genre :

SELECT tmpContrat.cContrat, tmpContrat.lContrat, TotHeure, TotPrix
FROM tmpContrat LEFT JOIN (SELECT tmpHeure.cContrat as Hcontrat, SUM(tmpHeureqHeure) as TotHeure FROM tmpHeure) ON tmpContrat=Hcontrat)
LEFT JOIN (SELECT tmpPrix.cContrat as Pcontrat, SUM (tmpPrix.mPrix) as TotCout FROM tmpPrix) ON tmpContrat=Pcontrat
GROUP BY tmpContrat.cContrat
ORDER BY tmpContrat.cContrat

 

Fait rapidement sans aucune vérification...

Lien vers le commentaire
Partager sur d’autres sites

Explication: c'est un produit cartésien.

Quand tu recherche cContrat=A

  • dans tmpHeure: 3 lignes
  • dans tmpPrix: 2 lignes

-> SQL server te construit toutes les combinaisons possibles avec ces 3 et 2 lignes --> 6 lignes

 

La réponse de RFN est pas mal, mais il manque les group by:

SELECT tmpContrat.cContrat, tmpContrat.lContrat, hParContrat.TotHeure, cParContrat.TotPrix
FROM tmpContrat
	LEFT JOIN (SELECT cContrat, SUM(tmpHeureqHeure) as TotHeure 
			  FROM tmpHeure
			  GROUP BY tempHeure.cContrat) hParContrat ON hParContrat.cContrat = tmpContrat.cContrat
	LEFT JOIN (SELECT cContrat, SUM (tmpPrix.mPrix) as TotCout 
               FROM tmpPrix
			   GROUP BY tmpPrix.cContrat) cParContrat ON cParContrat.cContrat = tmpContrat.cContrat

Une autre solution qui pourrait fonctionner différemment selon les tailles des bases, les index, le mode de récupération...

SELECT tmpContrat.cContrat, tmpContrat.lContrat, 
	(SELECT SUM(tmpHeureqHeure) FROM tmpHeure WHERE tempHeure.cContrat = tmpContrat.cContrat) TotHeure,
	(SELECT SUM (mPrix) FROM tmpPrix WHERE tempHeure.cContrat = tmpPrix.cContrat) TotCout
FROM tmpContrat

 

La différence entre les deux:

  • La première nécessite de l'espace pour construire les 2 sous-tables et renvoie tout le résultat en un bloc
  • La seconde sera plus lente, mais elle nécessite moins de mémoire et permet de renvoyer des résultats ligne à ligne...
Lien vers le commentaire
Partager sur d’autres sites

Parfait, Merci beaucoup.

Pour ceux qui voudraient reproduire le cas, les requêtes de @brice.wernet fonctionnelles :

SELECT tmpContrat.cContrat, tmpContrat.lContrat, hParContrat.TotHeure, cParContrat.TotCout
FROM tmpContrat
    LEFT JOIN (SELECT cContrat, SUM(qHeure) as TotHeure
              FROM tmpHeure
              GROUP BY tmpHeure.cContrat) hParContrat ON hParContrat.cContrat = tmpContrat.cContrat
    LEFT JOIN (SELECT cContrat, SUM (tmpPrix.mPrix) as TotCout
               FROM tmpPrix
               GROUP BY tmpPrix.cContrat) cParContrat ON cParContrat.cContrat = tmpContrat.cContrat
SELECT tmpContrat.cContrat, tmpContrat.lContrat,
    (SELECT SUM(qHeure) FROM tmpHeure WHERE tmpHeure.cContrat = tmpContrat.cContrat) TotHeure,
    (SELECT SUM (mPrix) FROM tmpPrix WHERE tmpPrix.cContrat = tmpContrat.cContrat) TotCout
FROM tmpContrat

Reste : qu'est-ce que j'ai fichu avec mes précédentes requêtes ??? Il faut que je les retrouve et que je vérifie 😱

À l’instant, Aloyse57 a écrit :

Reste : qu'est-ce que j'ai fichu avec mes précédentes requêtes ??? Il faut que je les retrouve et que je vérifie 😱

Ou je fais profil bas :siffle:

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...