SELECT A.*, B.MET_ID,B.MET_LIB, H.FCT_ID, C.FCT_LIB
, D.CT_ID,D.CT_LIB,J.CT_VALIDE
, E.TYP_ID,E.TYP_LIB, F.NOTFCT_VAL, I.SER_LIB
FROM COLLABORATEURS A
LEFT OUTER JOIN LI_COL_MET G
ON A.COL_ID=G.COL_ID
LEFT OUTER JOIN METIERS B
ON G.MET_ID=B.MET_ID
LEFT OUTER JOIN LI_COL_FCT H
ON A.COL_ID=H.COL_ID
LEFT OUTER JOIN FONCTION C
ON H.FCT_ID=C.FCT_ID
LEFT OUTER JOIN SERVICE I
ON A.SER_ID = I.SER_ID
INNER JOIN LI_COL_CT_FCT F
ON (A.COL_ID = F.COL_ID AND F.MET_ID = B.MET_ID)
INNER JOIN COMPETENCES_TECH D
ON F.CT_ID = D.CT_ID
INNER JOIN LI_MET_TYP_CT J
ON (J.CT_ID = D.CT_ID AND J.MET_ID = G.MET_ID)
INNER JOIN TYPE_CT E
ON J.TYP_ID = E.TYP_ID
ORDER BY A.COL_NOM ASC
, C.FCT_LIB ASC
, E.TYP_LIB ASC
, J.CT_VALIDE DESC
, D.CT_LIB ASC;
Note que les conditions de jointure dans ta requête de départ
(a.col_id=g.col_id(+) and g.met_id=b.met_id(+))
et
f.col_id=a.col_id and f.met_id=b.met_id
se contredisent : la première fait qu'on peut garder, pour la table B, des lignes "vides" (jointures externes), alors que la deuxième impose que b.met_id soit non nul... Tu peux imposer directement une jointure interne entre B et G, au lieu d'une jointure externe, tu pourrais gagner un peu en perf, et surtout en cohérence... et, du coup, aussi une jointure interne entre A et G.
Par ailleurs, les "SELECT table.*" sont à proscrire en règle générale (à l'exception, peut-être, d'applications du genre phpPgAdmin):
quelqu'un qui arrive après devra regarder le schéma complet de la table pour connaître toutes les colonnes que tu appelles ainsi
Oracle te renvoie toutes les colonnes, alors que tu n'en as peut-être pas besoin -> perte de perf
si tu changes le schéma de la table (ajout de colonnes), alors la requête les enverra aussi (cf. 2)
Oracle doit déterminer lui-même la liste des colonnes -> perte de perf par rapport à une requête où tu listes explicitement les colonnes.
# Un essai en sql propre...
Posté par alf . En réponse au message Problème de jointure multiple. Évalué à 3.