La réponse qui Pablo Santa Cruz gave est correct ; toutefois, au cas où quelqu'un tomberait sur cette page et souhaiterait plus de précisions, voici une ventilation détaillée.
Exemples de tableaux
Supposons que nous ayons les tableaux suivants :
-- t1
id name
1 Tim
2 Marta
-- t2
id name
1 Tim
3 Katarina
Joints internes
Un joint intérieur, comme ceci :
SELECT *
FROM `t1`
INNER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
Nous obtiendrions seulement les enregistrements qui apparaissent dans les deux tables, comme ceci :
1 Tim 1 Tim
Les jointures internes n'ont pas de direction (comme la gauche ou la droite) car elles sont explicitement bidirectionnelles - nous exigeons une correspondance des deux côtés.
Joints externes
Les jointures externes, quant à elles, servent à trouver des enregistrements qui n'ont peut-être pas de correspondance dans l'autre table. En tant que tel, vous devez spécifier de quel côté de la jointure est autorisé à avoir un enregistrement manquant.
LEFT JOIN
y RIGHT JOIN
sont des raccourcis pour LEFT OUTER JOIN
y RIGHT OUTER JOIN
Je vais utiliser leurs noms complets ci-dessous pour renforcer le concept de jointures externes par rapport aux jointures internes.
Jointure extérieure gauche
Une jointure externe gauche, comme ceci :
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
...nous obtiendrait tous les enregistrements de la table de gauche, qu'ils aient ou non une correspondance dans la table de droite, comme ceci :
1 Tim 1 Tim
2 Marta NULL NULL
Jointure extérieure droite
Un joint extérieur droit, comme ceci :
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
...nous obtiendrait tous les enregistrements de la table de droite, qu'ils aient ou non une correspondance dans la table de gauche, comme ceci :
1 Tim 1 Tim
NULL NULL 3 Katarina
Jointure externe complète
Une jointure externe complète nous donnerait tous les enregistrements des deux tables, qu'ils aient ou non une correspondance dans l'autre table, avec des NULL des deux côtés en cas d'absence de correspondance. Le résultat ressemblerait à ceci :
1 Tim 1 Tim
2 Marta NULL NULL
NULL NULL 3 Katarina
Toutefois, comme l'a souligné Pablo Santa Cruz, MySQL ne prend pas en charge cette fonctionnalité. Nous pouvons l'émuler en faisant une UNION d'une jointure gauche et d'une jointure droite, comme ceci :
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
UNION
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
Vous pouvez penser à un UNION
comme signifiant "exécuter ces deux requêtes, puis empiler les résultats l'un sur l'autre" ; certaines des lignes proviendront de la première requête et d'autres de la seconde.
Il convient de noter qu'un UNION
dans MySQL éliminera les doublons exacts : Tim apparaîtra dans les deux requêtes ici, mais le résultat de la requête UNION
ne le cite qu'une fois. Mon collègue gourou des bases de données estime qu'il ne faut pas se fier à ce comportement. Donc, pour être plus explicite à ce sujet, nous pourrions ajouter une balise WHERE
à la deuxième requête :
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
UNION
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
WHERE `t1`.`id` IS NULL;
D'autre part, si vous recherché pour voir les doublons pour une raison quelconque, vous pouvez utiliser UNION ALL
.
4 votes
Duplicata possible de Erreur de syntaxe de jointure externe complète MySQL
4 votes
Cette question a de meilleures réponses
6 votes
Méfiez-vous des réponses ici. La norme SQL dit que la jointure complète est une jointure interne sur les rangées union de toutes les rangées de table de gauche non appariées étendues par des nuls union de toutes les rangées de table de droite étendues par des nuls. La plupart des réponses données ici sont fausses (voir les commentaires) et celles qui ne sont pas fausses ne traitent pas le cas général. Même s'il y a beaucoup de votes positifs (injustifiés). (Voir ma réponse).
0 votes
Par exemple, j'ai une requête sur les ventes par état "état", "ventes" et une autre sur les dépenses par état "état", "dépenses", les deux requêtes utilisent group by("état"). Lorsque je fais l'union entre les jointures gauche et droite entre les deux requêtes, j'obtiens quelques lignes avec des ventes mais pas de dépenses, quelques autres avec des dépenses mais pas de ventes, tout est correct jusqu'à ce point, mais j'obtiens aussi quelques lignes avec à la fois des ventes et des dépenses et une colonne "état" répétée... ce n'est pas vraiment un problème mais ça ne semble pas correct...
1 votes
JairoLozano Les contraintes ne sont pas nécessaires pour effectuer des requêtes. Bien que lorsque les contraintes sont respectées, des requêtes supplémentaires renvoient la réponse souhaitée alors qu'elles ne le feraient pas autrement. Les contraintes n'affectent pas ce que la jointure complète renvoie pour des arguments donnés. Le problème que vous décrivez est que la requête que vous avez écrite est la mauvaise requête. (Probablement l'erreur commune où les gens veulent des jointures, chacune impliquant éventuellement une clé différente, de quelques sous-requêtes, chacune impliquant éventuellement une jointure et/ou une agrégation, mais ils essaient par erreur de faire toute la jointure puis toute l'agrégation ou d'agréger sur des agrégations précédentes).
4 votes
Toutes les réponses faisant UNION au lieu de UNION ALL sont incorrectes. toutes les réponses avec des sous-requêtes ou 3 sélections unies sont inefficaces. les réponses correctes feront une union all d'une jointure gauche avec une sélection de la seconde table avec un where not exists sur la première table (ou la jointure externe équivalente + condition where =NULL)
0 votes
Une partie du contenu de ce site fait l'objet de la question méta. Comment dois-je traiter une réponse incorrecte qui est acceptée et qui reçoit un nombre massif de votes positifs ? .