Jusqu’à présent, nos requêtes n’ont accédé qu’à une seule table à la fois. Les requêtes peuvent accéder à plusieurs tables à la fois, ou accéder à la même table de telle sorte que plusieurs lignes de la table soient traitées en même temps. Une requête qui accède à plusieurs lignes de la même table ou de tables différentes en une seule fois est appelée requête jointe. Par exemple, supposons que vous souhaitiez répertorier tous les enregistrements météorologiques avec l’emplacement de la ville associée. Pour ce faire, nous devons comparer la colonne ville de chaque ligne de la table météo avec la colonne nom de toutes les lignes de la table villes, et sélectionner les paires de lignes où ces valeurs correspondent.
Note : il s’agit uniquement d’un modèle conceptuel. La jointure est généralement effectuée d’une manière plus efficace que la comparaison réelle de chaque paire de lignes possible, mais cela est invisible pour l’utilisateur.
Ceci serait accompli par la requête suivante :
SELECT * FROM weather, cities WHERE city = name;
city | temp_lo | temp_hi | prcp | date | name | location---------------+---------+---------+------+------------+---------------+----------- San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53) San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)(2 rows)
Observez deux choses sur le jeu de résultats :
-
Il n’y a pas de ligne de résultat pour la ville de Hayward. C’est parce qu’il n’y a pas d’entrée correspondante dans la table
cities
pour Hayward, donc la jointure ignore les lignes non appariées dans la table météo. Nous verrons prochainement comment cela peut être corrigé. -
Il y a deux colonnes contenant le nom de la ville. Cela est correct car les listes de colonnes de la table
weather
et de la tablecities
sont concaténées. En pratique, cela n’est cependant pas souhaitable, et vous voudrez donc probablement lister les colonnes de sortie explicitement plutôt que d’utiliser *:SELECT city, temp_lo, temp_hi, prcp, date, location FROM weather, cities WHERE city = name;
Exercice : Essayez de découvrir la sémantique de cette requête lorsque la clause WHERE est omise.
Puisque les colonnes avaient toutes des noms différents, l’analyseur syntaxique a automatiquement trouvé à quelle table elles appartiennent, mais il est de bon style de qualifier complètement les noms de colonnes dans les requêtes de jointure :
SELECT weather.city, weather.temp_lo, weather.temp_hi, weather.prcp, weather.date, cities.location FROM weather, cities WHERE cities.name = weather.city;
Les requêtes de jointure du type vu jusqu’à présent peuvent également être écrites sous cette forme alternative :
SELECT * FROM weather INNER JOIN cities ON (weather.city = cities.name);
Cette syntaxe n’est pas aussi couramment utilisée que celle ci-dessus, mais nous la montrons ici pour vous aider à comprendre les sujets suivants.
Maintenant, nous allons déterminer comment nous pouvons récupérer les enregistrements de Hayward. Ce que nous voulons que la requête fasse est de balayer la table weather
et pour chaque ligne de trouver la ligne correspondante cities
. Si aucune ligne correspondante n’est trouvée, nous voulons que certaines « valeurs vides » soient substituées aux colonnes du tableau cities
. Ce type de requête s’appelle une jointure externe. (Les jointures que nous avons vues jusqu’à présent sont des jointures internes.) La commande ressemble à ceci:
SELECT * FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name); city | temp_lo | temp_hi | prcp | date | name | location---------------+---------+---------+------+------------+---------------+----------- Hayward | 37 | 54 | | 1994-11-29 | | San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53) San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)(3 rows)
Cette requête est appelée une jointure externe gauche parce que la table mentionnée à gauche de l’opérateur de jointure aura chacune de ses lignes dans la sortie au moins une fois, tandis que la table de droite aura seulement les lignes en sortie qui correspondent à une certaine ligne de la table de gauche. Lors de la sortie d’une ligne de la table de gauche pour laquelle il n’y a pas de correspondance avec la table de droite, des valeurs vides (nulles) sont substituées aux colonnes de la table de droite.
Exercice : Il existe également des jointures externes de droite et des jointures externes complètes. Essayez de trouver ce qu’elles font.
On peut aussi joindre une table contre elle-même. C’est ce qu’on appelle une auto-jonction. A titre d’exemple, supposons que nous souhaitons trouver tous les enregistrements météo qui sont dans la plage de température d’autres enregistrements météo. Nous devons donc comparer les colonnes temp_lo et temp_hi de chaque ligne weather
aux colonnes temp_lo et temp_hi de toutes les autres lignes weather
. Nous pouvons le faire avec la requête suivante:
SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high, W2.city, W2.temp_lo AS low, W2.temp_hi AS high FROM weather W1, weather W2 WHERE W1.temp_lo < W2.temp_lo AND W1.temp_hi > W2.temp_hi; city | low | high | city | low | high---------------+-----+------+---------------+-----+------ San Francisco | 43 | 57 | San Francisco | 46 | 50 Hayward | 37 | 54 | San Francisco | 46 | 50(2 rows)
Ici, nous avons renommé la table météo en W1 et W2 pour pouvoir distinguer le côté gauche et le côté droit de la jointure. Vous pouvez également utiliser ce type d’alias dans d’autres requêtes pour économiser de la frappe, par exemple :
SELECT * FROM weather w, cities c WHERE w.city = c.name;
Vous rencontrerez ce style d’abréviation assez fréquemment.