Définissez une jointure externe
Lorsque vous écrivez une jointure interne entre 2 tables, certaines lignes de la première ou de la seconde table peuvent être absentes du résultat de votre jointure. Voyons dans cette vidéo quelle en est la cause, et comment y remédier :
Dans la table entity
, il y a des sociétés dont on ne connaît pas l'adresse. Pour ces sociétés, la valeur de id_address
sera vide. En informatique, et notamment en SQL, une valeur vide est appelée valeur nulle, notée NULL
:
Id | Name | id_address |
0 | BigData Crunchers Ltd. | 10000000 |
1000000004 | Dewberries, Garlics &Bittercress Limited | NULL |
1000000007 | Snakeberries, Bittercress& Maples Corporation | NULL |
Mais au chapitre précédent, on avait utilisé cette condition de jointure : entity.id_address = address.id_address
. Ici, si entity.id_address
est nul, alors ça ne va plus marcher !
Exactement ! En effet address.id_address
est la clé primaire de la table address
. Comme c'est une clé primaire, elle ne peut pas contenir de valeurs nulles. Or, comme ici entity.id_address
sera nul pour certaines sociétés, alors la condition de jointure ne sera pas satisfaite pour ces lignes, c'est-à-dire pour les sociétés qui n'ont pas d'adresse. Comme cette condition de jointure est en fait une condition de filtrage, ces lignes seront écartées…
Pour garder toutes les lignes de entity
, même celles qui n'ont pas trouvé de correspondance dans la table address
, on va utiliser une jointure externe à gauche (on considère que entity est à gauche car c'est la 1e table à être citée dans la requête) :
SELECT *
FROM entity
LEFT OUTER JOIN address ON entity.id_address = address.id_address;
Si au contraire, nous voulons garder toutes les adresses (qu'elles correspondent à une société ou non), il faut alors faire une jointure externe à droite :
SELECT *
FROM entity
RIGHT OUTER JOIN address ON entity.id_address = address.id_address;
Vous me voyez venir...? Oui ! Il ne me reste plus qu'à vous donner la syntaxe de la jointure entière ! Celle-ci nous permet de garder à la fois toutes les adresses et toutes les sociétés :
SELECT *
FROM entity
FULL OUTER JOIN address ON entity.id_address = address.id_address;
Au chapitre précédent, on avait dit que quand on fait une jointure interne d'une clé étrangère d'une table A
vers la clé primaire d'une table B
, le résultat contient au plus autant de lignes que la table A
.
Pourquoi “au plus”? Car pour une jointure interne, certaines lignes pouvaient être ignorées si elles ne trouvaient pas de correspondances dans l'autre table.
Mais avec la jointure externe, on garde les lignes qui n'ont pas de correspondance ; le résultat aura donc exactement autant de lignes que la table A
.
type | depuis | vers | nombre de lignes |
Jointure interne | depuis une clé étrangère d'une table A (table de gauche) | vers une potentielle clé primaire d'une table B (table de droite) | au plus autant de lignes que la table A |
Jointure externe gauche |
|
| exactement autant de lignes que la table A |
Découvrez la jointure naturelle
Il arrive parfois que dans une condition de jointure, les colonnes des clés étrangères et clés primaires aient les mêmes noms. Dans ce cas, on peut simplifier l'écriture de la requête. C'est ce que nous allons voir dans cette vidéo.
Voici la requête correspondante :
SELECT
e.id AS id_entity,
e.name AS nom_societe,
e.id_address AS 'e.id_address',
a.id_address AS 'a.id_address',
a.address,
a.countries
FROM
entity e
NATURAL JOIN
address a ;
À vous de jouer
Contexte
Explorer des données, c’est aussi vérifier leur qualité : sont-elles fiables, sont-elles cohérentes ? Dans un souci de cohérence, vous décidez de vérifier si certaines adresses ne sont pas liées à des sociétés. Si c’est le cas, alors pourquoi se retrouvent-elles dans la base de données ? Ce sera une question à élucider.
Consignes
La requête de la précédente vidéo effectue une jointure externe gauche, afin de garder toutes les lignes de entity qui n'ont pas de correspondance :
SELECT
e.id AS id_entity,
e.name AS nom_societe,
e.id_address AS 'e.id_address',
a.id_address AS 'a.id_address',
a.address,
a.countries
FROM
entity e
LEFT JOIN
address a ON e.id_address = a.id_address ;
Transformez cette requête pour garder les adresses qui n'ont pas de société (plus besoin par contre de garder les sociétés sans adresse).
Vérifiez votre travail
Voici la requête que vous devez obtenir :
SELECT
e.id AS id_entity,
e.name AS nom_societe,
e.id_address AS 'e.id_address',
a.id_address AS 'a.id_address',
a.address,
a.countries
FROM
address a
LEFT JOIN
entity e ON e.id_address = a.id_address ;
Il y a en effet beaucoup d’adresses qui ne correspondent pas à des sociétés de entity
. Mais en y regardant d’un peu plus près, on voit que la table intermediary
a elle aussi une clé étrangère référençant la table address
. Les adresses qui ne correspondent pas à une société correspondent donc probablement à des intermédiaires !
En résumé
Pour garder toutes les informations de l'une des tables (ou des 2 tables), il faut utiliser une jointure externe.
Une jointure externe à gauche garde toutes les lignes de la table de gauche.
Rappel de syntaxes :
jointure externe gauche :
LEFT OUTER JOIN
jointure externe droite :
RIGHT OUTER JOIN
jointure externe totale :
FULL OUTER JOIN
Maintenant que vous êtes un as dans l'art de manier les jointures, il est temps de prendre un peu de recul sur tout ce que nous avons appris jusqu'à maintenant.