La jointure : sélection sur plusieurs tables

Une jointure permet de rassembler des tables qui sont en relation.
Il en existe de plusieurs sortes, principalement les jointures internes et les jointures externes. Le mot clé NATURAL permet de faire abstraction de la clé utilisée quand il n'y a pas d'ambiguité. Il s'utilise pour les jointures internes (JOIN simple ou INNER JOIN) ; mais également pour les jointures externes comme NATURAL LEFT OUTER JOIN et NATURAL RIGHT OUTER JOIN.
Ceci n'est pas toujours possible. En effet, il arrive que certaines tables soient reliées par plusieurs clés. Il faut alors préciser sur une représentation Merise ou UML par exemple le nom de la relation.
De même, une table peut être reliée à elle même c'est le cas de toutes les structures d'arbres ou de schéma avec des notions de pères (ou mères).

Avant la version 8 de son SGBD, Oracle avait une manière particulière d'écrire les jointures externes. Celle-ci a gardé sa compatibilité avec les versions suivantes et de nombreux DBA l'utilisent encore même si elle n'est pas recommandée lorsque l'on démarre sur une version supérieure : utilisation d'un (+) dans les conditions du where sur la colonne acceptant la valeur nulle. Cette méthode est explicitée ci-après, à titre informatif.



Voici les ordres SQL des différents types de jointures et les correspondances de chacune :
La jointure la plus simple est la jointure interne, elle correspond à une relation (1-1..n) :

SELECT t1.a, t2.b FROM t1 NATURAL JOIN t2


SELECT t1.a, t2.b FROM t1 INNER JOIN t2 using (id_t1)


SELECT t1.a, t2.b FROM t1 INNER JOIN t2 ON t1.id_t1 = t2.id_t1


SELECT t1.a, t2.b FROM t1, t2 WHERE t1.id_t1 = t2.id_t1


LEFT JOIN ou LEFT OUTER JOIN qui sont strictement identiques (correspond à une relation de type [1 - 0..n ]) :


SELECT t1.a, t2.b FROM t1 LEFT OUTER JOIN t2 using (id_t1)

SELECT t1.a, t2.b FROM t1 LEFT OUTER JOIN t2 ON t1.id_t1 = t2.id_t1

SELECT t1.a, t2.b FROM t1, t2 WHERE t1.id_t1 = t2.id_t1 OR t2.id_t1 is null

SELECT t1.a, t2.b FROM t2 NATURAL LEFT OUTER JOIN t2

SELECT t1.a , t2.b FROM t1 ,t2 WHERE ti = t2(+)


RIGHT JOIN ou RIGHT OUTER JOIN qui sont strictement identiques (correspond à une relation de type [0..n - 1]) :


SELECT t1.a, t2.b FROM t1 RIGHT OUTER JOIN t2 using (id_t1)

SELECT t1.a, t2.b FROM t1 RIGHT OUTER JOIN t2 ON t1.id_t1 = t2.id_t1

SELECT t1.a, t2.b FROM t2 LEFT OUTER JOIN t2 using (id_t1)

SELECT t1.a, t2.b FROM t2 LEFT OUTER JOIN t2 ON t1.id_t1 = t2.id_t1

SELECT t1.a, t2.b FROM t1, t2 WHERE t1.id_t1 = t2.id_t1 OR t1.id_t1 is null

SELECT t1.a, t2.b FROM t2 NATURAL RIGHT OUTER JOIN t2

SELECT t1.a, t2.b FROM t1 ,t2 WHERE ti (+)= t2

CROSS JOIN (encore appelé produit cartésien) n'utilise pas de critères de rassemblement :


SELECT t1.a, t2.b FROM t1, t2

SELECT t1.a, t2.b FROM t1 cross JOIN t2




Les sous-requêtes peuvent toujours être réécrites sous forme de jointure, selon les SGBD, elles ne sont pas systématiquement disponibles, vous pouvez alors vous baser sur ces exemples simples pour les réécrire :

ex 1 :
SELECT t1.a FROM t1 WHERE t1.id_t1 IN
( SELECT t2.id_t1 FROM t2 )


SELECT t1.a FROM t1 LEFT OUTER JOIN t2 using (id_t1)
WHERE t2.id_t1 is NOT NULL



ex 2 :

SELECT t1.a FROM t1 WHERE t1.id_t1 NOT IN
( SELECT t2.id_t1 FROM t2 )


SELECT t1.a FROM t1 LEFT OUTER JOIN t2 using (id_t1)
WHERE t2.id_t1 is null


Ces différentes écritures de requêtes correspondent initialement à des modes de recherches différents. Cependant, Oracle, via l'optimiseur (CBO), va utiliser la méthode la plus adéquate. Sauf dans le cas où on lui précise (via un hint) la méthode de jointure. Les types de jointure qui existent sont:
- nested loop (hint use_nl) qui correspond à une sous jointure (select .. where .. in (select ...)).

- hash join (hint use_hash) correspond à une jointure via tables de hashage (select ... join .. on ..).
Dans l'algorithme de recherche par hash join, l'ensemble de la requête correspondant à la la table de droite est examinée, la requête sur la table de gauche utilise alors le résultat (stocké dans une table de hashage, d'où le nom) pour l'utiliser au même titre que les autres conditions.

- merge join (hint use_merge) correspond à un produit cartésien des tables en prenant les conditions d'égalité comme un filtre (select ... from ... , ... where ... = ... ...).

Pour aller plus loin, vous pouvez consulter l'article correspondant au choix du plan d'exécution.

Il est tout à fait possible d'écrire des requêtes multi-jointures interrogeant 3, 4, ... 50 tables :
SELECT t1.a, t2.b, t3.c FROM t1 INNER JOIN t2 ON t1.id_t1 = t2.id_t1
INNER JOIN t3 ON t3.id_t2 = t2.id_t2

A savoir aussi, qu'Oracle ne permet pas de créer des requêtes comportant un nombre de colonnes supérieur à 1000 : ORA-01792.

Voir aussi :
- Clés primaires et étrangères : mettre en place ses contraintes d'intégrité
- Les colonnes virtuelles en 11g
- Les tables partitionnées
- Améliorer les performances d'une vue
- Gérer l'auto-increment sous Oracle




Vous n'avez pas trouver réponse à votre question ? Préciser votre recherche :

Catégories