Jump to content

SQL Jointure sur 3 tables


Recommended Posts

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

Link to post
Share on other 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...

Link to post
Share on other 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...
  • Thanks 2
Link to post
Share on other 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:

Link to post
Share on other sites
  • 1 month later...

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...