MySQL: répartition rapide des types de jointures


157

Je voudrais un aperçu rapide des types de jointures MySQL. Je sais de ces derniers, le reste je ne sais pas ce qu'ils signifient.

  • séparés par des virgules (à quoi correspond exactement ce raccourci?)SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • afficher les informations de a, même s'il n'y a pas de correspondance dans b: SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...

J'ai vu d'autres jointures, mais je veux savoir ce qui les rend différentes, ce qui est INNER/ OUTER, ajoute des LEFTchoses de changement.

Je sais déjà comment fonctionnent les jointures, je veux juste savoir s'il existe d'autres types de jointures ou si ce sont simplement des façons différentes d'obtenir le même résultat.


Réponses:


463

3
+1 mais les deux manquent cross join, ce qui fait un produit cartésien.
Denis de Bernardy

11
@denis: regardez de plus près le lien codinghorror.com:There's also a cartesian product or cross join, which as far as I can tell, can't be expressed as a Venn diagram:
Rufinus

1
Je suis étonné d'imprimer ces schémas et de les mettre sur le mur de mon bureau. vous avez changé ma vie!
yossico

41
La question concerne spécifiquement MySQL. MySQL ne prend pas en charge les jointures FULL OUTER.
Mike Baranczak

4
et bien sûr, cela devrait être une raison pour ne pas publier ce graphique. soupir
Rufinus

27

Sur la base de votre commentaire, les définitions simples de chacun se trouvent mieux dans W3Schools La première ligne de chaque type donne une brève explication du type de jointure

  • JOIN: renvoie des lignes lorsqu'il y a au moins une correspondance dans les deux tables
  • JOINT GAUCHE: renvoie toutes les lignes de la table de gauche, même s'il n'y a pas de correspondance dans la table de droite
  • JOINDRE DROITE: renvoie toutes les lignes de la table de droite, même s'il n'y a pas de correspondance dans la table de gauche
  • FULL JOIN: renvoie des lignes lorsqu'il y a une correspondance dans l'une des tables

FIN DE LA MODIFICATION

En un mot, l'exemple séparé par des virgules que vous avez donné

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

sélectionne chaque enregistrement des tables a et b avec les virgules séparant les tables, cela peut également être utilisé dans des colonnes comme

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

Il obtient alors les informations demandées dans la ligne où la colonne b.id et la colonne a.beeId ont une correspondance dans votre exemple. Donc, dans votre exemple, il obtiendra toutes les informations des tables a et b où le b.id est égal à a.beeId. Dans mon exemple, il obtiendra toutes les informations de la table b et uniquement les informations de la colonne a.beeName lorsque le b.id est égal à a.beeId. Notez qu'il existe également une clause AND, cela vous aidera à affiner vos résultats.

Pour des tutoriels simples et des explications sur les jointures mySQL et les jointures gauches, jetez un œil aux tutoriels mySQL de Tizag. Vous pouvez également consulter le site Web de Keith J. Brown pour plus d'informations sur les jointures qui sont également très bonnes.

J'espère que ceci vous aide


Il se trouve que je sais déjà tout cela. Je cherchais en fait les types de jointures qu'il existe. Désolé, je n'ai pas été clair sur ce que je sais déjà. Mais je ne cherchais pas une longue documentation juste pour obtenir un résumé rapide.
Bryan Field

Une autre référence dans la réponse ... pourrait être plus de ce que vous voulez mec.
Ryan

+1 pour cette modification. Je ne suis pas partisan de W3Schools comme certaines personnes semblent l'être. Peut-être n'ai-je pas beaucoup vu les mauvais côtés ou peut-être est-ce juste une «guerre sainte». De plus, j'ai édité le contenu de W3Schools, j'espère que cela ne vous dérange pas, mais n'hésitez pas à faire les modifications que vous voulez. Tous ces visuels dans la réponse acceptée sont agréables, mais certains sont en fait des variations de la même jointure. C'est une bonne alternative.
Bryan Field

Merci George, cela ne me dérange pas du tout, à condition que l'édition soit correcte! Je suis convaincu que les gens ont besoin de trouver les sources qui leur conviennent, plus ou moins d'informations, beaucoup d'exemples ou aucun. Les W3Schools sont précis et concis, ils ont tendance à avoir de bons exemples également, Tizag est similaire. Take it easy mate
Ryan

1
il n'y a pas de FULL JOIN dans mysql, donc ces liens ne sont pas très utiles.
Ether

13

J'ai 2 tables comme celle-ci:

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+

> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER JOIN se soucie des deux tables

INNER JOIN se soucie des deux tables, donc vous n'obtenez une ligne que si les deux tables en ont une. S'il y a plus d'une paire correspondante, vous obtenez plusieurs lignes.

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

Cela ne fait aucune différence pour INNER JOIN si vous inversez l'ordre, car il se soucie des deux tables:

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

Vous obtenez les mêmes lignes, mais les colonnes sont dans un ordre différent car nous avons mentionné les tables dans un ordre différent.

LEFT JOIN ne se soucie que de la première table

LEFT JOIN se soucie de la première table que vous lui donnez, et ne se soucie pas beaucoup de la seconde, donc vous obtenez toujours les lignes de la première table, même s'il n'y a pas de ligne correspondante dans la seconde:

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

Ci-dessus, vous pouvez voir toutes les lignes de table_a même si certaines d'entre elles ne correspondent à rien de la table b, mais pas toutes les lignes de table_b - seulement celles qui correspondent à quelque chose dans table_a.

Si nous inversons l'ordre des tables, LEFT JOIN se comporte différemment:

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

Nous obtenons maintenant toutes les lignes de table_b, mais uniquement les lignes correspondantes de table_a.

RIGHT JOIN ne se soucie que de la deuxième table

a RIGHT JOIN bvous donne exactement les mêmes lignes que b LEFT JOIN a. La seule différence est l'ordre par défaut des colonnes.

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

Il s'agit des mêmes lignes que celles table_b LEFT JOIN table_aque nous avons vues dans la section LEFT JOIN.

De même:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

Est les mêmes lignes que table_a LEFT JOIN table_b.

Aucune jointure du tout vous donne des copies de tout

Clause No Join: Si vous écrivez vos tables sans aucune clause JOIN, juste séparées par des virgules, vous obtenez chaque ligne de la première table écrite à côté de chaque ligne de la deuxième table, dans toutes les combinaisons possibles:

> SELECT * FROM table_b, table_a;        
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(Ceci est tiré de mon article de blog Exemples de types de jointures SQL )


@Anu S'il vous plaît, ne faites pas de modifications aussi insignifiantes lorsque votre mauvaise réputation signifie que vos modifications doivent être examinées par d'autres, vous perdez simplement leur temps. Cette modification aurait dû être rejetée car aucune différence. Le code que vous avez modifié n'était pas vraiment faux et vous auriez pu commenter.
philipxy

@philipxy D'accord. Noté avec cela. Pendant que j'essayais de comprendre l'explication, j'ai vu une telle faute de frappe et c'est pourquoi édité pour le rendre plus clair. En effet, c'est une bonne réponse et mon intention était de la garder plus juste.
Anu

@Anu Cette réponse a les mêmes descriptions incomplètes fragmentées que dans la plupart des réponses. Il ne dit pas vraiment quelle est la sortie en fonction des entrées. Voir aussi presque toutes les réponses au duplicata proposé et mes commentaires sur les deux pages. Voir aussi ma réponse ici. PS Je viens de voir par coïncidence cela d'hier re-révisé la taille de l'édition (bien sûr, il y a beaucoup plus de messages liés à Meta Stack Overflow & Meta Stack Exchange .)
philipxy

11

La jointure externe complète n'existe pas dans mysql, vous devrez peut-être utiliser une combinaison de jointure gauche et droite.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.