Quelle est la différence entre «INNER JOIN» et «OUTER JOIN»?

4672

Aussi comment faire LEFT JOIN, RIGHT JOINet FULL JOINdans tout ça?

Chris de Vries
la source
64
Parmi les réponses et commentaires et leurs références ci-dessous, un seul explique en fait comment les diagrammes de Venn représentent les opérateurs: La zone d'intersection du cercle représente l'ensemble des lignes dans A JOIN B.La zone unique à chaque cercle représente l'ensemble des lignes que vous obtenez en prenant son les lignes de la table qui ne participent pas à A JOIN B et l'ajout de colonnes uniques à l'autre table sont toutes définies sur NULL. (Et la plupart donnent une vague correspondance bidon des cercles à A et B.)
philipxy
1
Passer des réponses théoriques ci-dessous à une application du monde réel: je travaille souvent avec des données d'expérimentation, en exécutant des tests de performance sur les conceptions de processeurs. Souvent, je souhaite comparer les résultats entre 2 ou plusieurs options matérielles. INNER JOIN signifie que je ne vois que les repères qui ont fonctionné avec succès dans toutes les expériences; OUTER JOIN signifie que je peux voir toutes les expériences, y compris celles qui n'ont pas pu s'exécuter sur certaines configurations. Il est important de voir les échecs dans ces expériences, ainsi que les succès. Assez important que j'ai écrit PerlSQL pour obtenir OUTER JOIN, lorsque de nombreux SGBDR en manquaient,
Krazy Glew
4
Beaucoup de réponses sont déjà fournies mais je n'ai pas vu ce tutoriel mentionné. Si vous connaissez les diagrammes de Venn, ceci est un excellent tutoriel: blog.codinghorror.com/a-visual-explanation-of-sql-joins Pour moi, c'est assez concis pour être une lecture rapide mais saisit tout le concept et fonctionne tous les très bien. Si vous ne savez pas ce que sont les diagrammes de Venn - apprenez-les. Cela prend 5 à 10 minutes pour le faire et vous aidera chaque fois que vous aurez besoin de visualiser le travail avec des ensembles et de gérer les opérations sur les ensembles.
DanteTheSmith
15
@DanteTheSmith Non, cela souffre des mêmes problèmes que les diagrammes ici. Voir mon commentaire ci-dessus concernant la question et ci-dessous concernant ce même article de blog: "Jeff répudie son blog quelques pages plus bas dans les commentaires". Les diagrammes de Venn montrent les éléments en ensembles. Essayez juste d'identifier exactement quels sont les ensembles et quels sont les éléments dans ces diagrammes. Les ensembles ne sont pas les tables et les éléments ne sont pas leurs lignes. De plus, deux tables peuvent être jointes, les PK et FK ne sont donc pas pertinents. Tout faux. Vous faites exactement ce que des milliers d'autres ont fait - vous avez une vague impression que vous supposez (à tort) logique.
philipxy
3
Chris Je vous recommande de lire cet article: versdatascience.com/… ... et d'envisager de changer votre choix de réponse acceptée (peut-être celle avec la prime) en une réponse qui n'utilise pas les diagrammes de Venn. La réponse actuellement acceptée trompe trop de gens. Je vous exhorte à le faire pour le bien de notre communauté et la qualité de notre base de connaissances.
Colm Bhandal

Réponses:

6116

En supposant que vous vous joignez à des colonnes sans doublons, ce qui est un cas très courant:

  • Une jointure intérieure de A et B donne le résultat d'une intersection de A B, c'est-à-dire la partie intérieure d'une intersection de diagramme de Venn .

  • Une jointure externe de A et B donne les résultats de l'union B, c'est-à-dire les parties externes d'une union de diagramme de Venn.

Exemples

Supposons que vous ayez deux tables, avec une seule colonne chacune, et les données comme suit:

A    B
-    -
1    3
2    4
3    5
4    6

Notez que (1,2) sont uniques à A, (3,4) sont communs et (5,6) sont uniques à B.

Jointure interne

Une jointure interne utilisant l'une des requêtes équivalentes donne l'intersection des deux tables, c'est-à-dire les deux lignes qu'elles ont en commun.

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

a | b
--+--
3 | 3
4 | 4

Jointure externe gauche

Une jointure externe gauche donnera toutes les lignes dans A, plus toutes les lignes communes dans B.

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4

Jointure extérieure droite

Une jointure externe droite donnera toutes les lignes en B, plus toutes les lignes communes en A.

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6

Jointure externe complète

Une jointure externe complète vous donnera l'union de A et B, c'est-à-dire toutes les lignes dans A et toutes les lignes dans B. Si quelque chose dans A n'a pas de donnée correspondante dans B, alors la partie B est nulle, et vice inversement.

select * from a FULL OUTER JOIN b on a.a = b.b;

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5
Mark Harrison
la source
42
Il serait bon d'augmenter l'exemple en ajoutant une autre ligne dans le tableau B avec la valeur 4. Cela montrera que les jointures internes n'ont pas besoin d'être sur un nombre égal de lignes.
softveda
473
Une excellente explication, cependant, cette affirmation: Une jointure externe de A et B donne les résultats de l'union B, c'est-à-dire les parties externes d'une union de diagramme de Venn. n'est pas formulé avec précision. Une jointure externe donnera les résultats de A intersecter B en plus de l'un des éléments suivants: tout A (jointure gauche), tout B (jointure droite) ou tout A et tout B (jointure complète). Seul ce dernier scénario est vraiment une union B. Pourtant, une explication bien écrite.
Thomas
11
Ai-je raison de dire que FULL JOIN est un alias de FULL OUTER JOIN et LEFT JOIN est un alias de LEFT OUTER JOIN?
Damian
3
oui grande et excellente explication. mais pourquoi dans la colonne b les valeurs ne sont pas en ordre? c'est-à-dire qu'il est 6,5 et non 5,6?
Ameer
7
@Ameer, merci. Join ne garantit pas une commande, vous devez ajouter une clause ORDER BY.
Mark Harrison
734

Les diagrammes de Venn ne le font pas vraiment pour moi.

Ils ne montrent aucune distinction entre une jointure croisée et une jointure interne, par exemple, ou plus généralement ne montrent aucune distinction entre différents types de prédicat de jointure ou fournissent un cadre pour raisonner sur la façon dont ils fonctionneront.

Il n'y a pas de substitut à la compréhension du traitement logique et il est de toute façon relativement simple à saisir.

  1. Imaginez une jointure croisée.
  2. Évaluez la onclause par rapport à toutes les lignes de l'étape 1 en conservant celles où le prédicat est évalué.true
  3. (Pour les jointures externes uniquement), ajoutez à nouveau les lignes externes perdues à l'étape 2.

(NB: en pratique, l'optimiseur de requêtes peut trouver des moyens plus efficaces d'exécuter la requête que la description purement logique ci-dessus mais le résultat final doit être le même)

Je vais commencer par une version animée d'une jointure externe complète . D'autres explications suivent.

entrez la description de l'image ici


Explication

Tableaux source

entrez la description du lien ici

Commencez d'abord par un CROSS JOIN(produit cartésien AKA). Cela n'a pas de ONclause et renvoie simplement chaque combinaison de lignes des deux tables.

SÉLECTIONNEZ A.Couleur, B.COLORE À PARTIR D'UNE CROIX JOIGNEZ B

entrez la description du lien ici

Les jointures internes et externes ont un prédicat de clause "ON".

  • Jointure interne. Évaluez la condition dans la clause "ON" pour toutes les lignes du résultat de la jointure croisée. Si vrai, renvoyez la ligne jointe. Sinon, jetez-le.
  • Jointure externe gauche. Identique à la jointure interne, puis pour toutes les lignes de la table de gauche qui ne correspondent à rien, affichez-les avec des valeurs NULL pour les colonnes de la table de droite.
  • Jointure extérieure droite. Identique à la jointure interne, puis pour toutes les lignes de la table de droite qui ne correspondent à rien, affichez-les avec des valeurs NULL pour les colonnes de la table de gauche.
  • Jointure externe complète. Identique à la jointure interne, puis conservez les lignes gauches non appariées comme dans la jointure externe gauche et les lignes non appariées droites selon la jointure externe droite.

Quelques exemples

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UN JOINT INTÉRIEUR B SUR A.Colour = B.Colour

Ce qui précède est la jointure équi classique.

Jointure interne

Version animée

entrez la description de l'image ici

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UN INTÉRIEUR JOIGNEZ B SUR A.Colour NOT IN ('Vert', 'Bleu')

La condition de jointure interne ne doit pas nécessairement être une condition d'égalité et elle n'a pas besoin de référencer des colonnes des deux (ou même des deux) des tables. Évaluation A.Colour NOT IN ('Green','Blue')sur chaque ligne du retour de jointure croisée.

intérieur 2

SÉLECTIONNEZ A.Couleur, B.Couleur À PARTIR D'UN INTÉRIEUR JOINDRE B SUR 1 = 1

La condition de jointure a la valeur true pour toutes les lignes du résultat de la jointure croisée, c'est donc la même chose qu'une jointure croisée. Je ne répéterai pas l'image des 16 lignes.

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UNE GAUCHE EXTÉRIEURE JOINDRE B SUR A.Colour = B.Colour

Les jointures externes sont évaluées logiquement de la même manière que les jointures internes, sauf que si une ligne de la table de gauche (pour une jointure de gauche) ne se joint à aucune ligne de la table de droite, elle est conservée dans le résultat avec des NULLvaleurs pour le colonnes de droite.

LOJ

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UNE GAUCHE EXTÉRIEURE JOIGNEZ B SUR A.Colour = B.Colour O B. B.Colour EST NULL

Cela limite simplement le résultat précédent pour ne renvoyer que les lignes où B.Colour IS NULL. Dans ce cas particulier, ce seront les lignes qui ont été conservées car elles ne correspondaient pas dans le tableau de droite et la requête renvoie la seule ligne rouge non correspondante dans le tableau B. C'est ce qu'on appelle un anti semi jointure.

Il est important de sélectionner une colonne pour le IS NULLtest qui ne soit pas annulable ou pour laquelle la condition de jointure garantit que toutes les NULLvaleurs seront exclues pour que ce modèle fonctionne correctement et éviter de simplement ramener des lignes qui se trouvent avoir une NULLvaleur pour cela. en plus des lignes non appariées.

loj est nul

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UN DROIT EXTÉRIEUR JOINDRE B SUR A.Colour = B.Colour

Les jointures externes droites agissent de la même manière que les jointures externes gauche, sauf qu'elles conservent les lignes non correspondantes du tableau de droite et étendent null les colonnes de gauche.

ROJ

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UN EXTÉRIEUR COMBINER B SUR A.Colour = B.Colour

Les jointures externes complètes combinent le comportement des jointures gauche et droite et préservent les lignes non correspondantes des tables gauche et droite.

FOJ

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UNE EXTÉRIEURE COMPLÈTE JOINDRE B SUR 1 = 0

Aucune ligne de la jointure croisée ne correspond au 1=0prédicat. Toutes les lignes des deux côtés sont conservées à l'aide des règles de jointure externe normales avec NULL dans les colonnes du tableau de l'autre côté.

FOJ 2

CHOISIR COALESCE (A.Colour, B.Colour) COMME COULEUR À PARTIR D'UNE EXTÉRIEURE COMPLÈTE JOINDRE B SUR 1 = 0

Avec une modification mineure de la requête précédente, on pourrait simuler l'une UNION ALLdes deux tables.

UNION ALL

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UNE GAUCHE EXTÉRIEURE JOIGNEZ B SUR A.Colour = B.Colour OERE B.Colour = 'Green'

Notez que la WHEREclause (si présente) s'exécute logiquement après la jointure. Une erreur courante consiste à effectuer une jointure externe gauche, puis à inclure une clause WHERE avec une condition sur la table de droite qui finit par exclure les lignes non correspondantes. Ce qui précède finit par effectuer la jointure externe ...

LOJ

... Et puis la clause "Where" s'exécute. NULL= 'Green'n'évalue pas true donc la ligne conservée par la jointure externe finit par être rejetée (avec la bleue) en convertissant efficacement la jointure en une interne.

LOJtoInner

Si l'intention était d'inclure uniquement les lignes de B où Color est vert et toutes les lignes de A, quelle que soit la syntaxe correcte,

SÉLECTIONNEZ A.Colour, B.Colour À PARTIR D'UNE GAUCHE EXTÉRIEURE JOIGNEZ B SUR A.Colour = B.Colour ET B.Colour = 'Green'

entrez la description de l'image ici

SQL Fiddle

Découvrez ces exemples en direct sur SQLFiddle.com .

Martin Smith
la source
46
Je dirai que bien que cela ne fonctionne pas pour moi presque aussi bien que les diagrammes de Venn, j'apprécie que les gens varient et apprennent différemment et c'est une explication très bien présentée contrairement à toutes celles que j'ai vues auparavant, donc je soutiens @ypercube dans attribution des points bonus. Aussi un bon travail expliquant la différence de mettre des conditions supplémentaires dans la clause JOIN par rapport à la clause WHERE. Bravo à vous, Martin Smith.
Old Pro
22
@OldPro Les diagrammes de Venn sont OK dans la mesure où ils vont, je suppose, mais ils sont silencieux sur la façon de représenter une jointure croisée, ou de différencier un type de prédicat de jointure tel que la jointure équi d'une autre. Le modèle mental consistant à évaluer le prédicat de jointure sur chaque ligne du résultat de jointure croisée, puis à ajouter des lignes inégalées si une jointure externe et enfin à évaluer où fonctionne mieux pour moi.
Martin Smith
18
Les diagrammes de Venn sont bons pour représenter les unions et les intersections et les différences, mais pas les jointures. Ils ont une valeur éducative mineure pour les jointures très simples, c'est-à-dire les jointures où la condition de jointure se trouve sur des colonnes uniques.
ypercubeᵀᴹ
12
@Arth - Non, vous vous trompez. SQL Fiddle sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/5155 c'est quelque chose que les diagrammes de Venn ne peuvent pas illustrer.
Martin Smith
7
@MartinSmith Wow, je suis d'accord, je me trompe totalement! Trop habitué à travailler avec one-to-manys .. merci pour la correction.
Arth
188

Les jointures sont utilisées pour combiner les données de deux tables, le résultat étant une nouvelle table temporaire. Les jointures sont effectuées sur la base d'un élément appelé prédicat, qui spécifie la condition à utiliser pour effectuer une jointure. La différence entre une jointure interne et une jointure externe est qu'une jointure interne ne renverra que les lignes qui correspondent réellement en fonction du prédicat de jointure. Par exemple, considérons le tableau des employés et des emplacements:

entrez la description de l'image ici

Jointure interne: - La jointure interne crée une nouvelle table de résultats en combinant les valeurs de colonne de deux tables ( employé et emplacement ) en fonction du prédicat de jointure. La requête compare chaque ligne d' employé à chaque ligne d' emplacement pour trouver toutes les paires de lignes qui satisfont le prédicat de jointure. Lorsque le prédicat de jointure est satisfait en faisant correspondre des valeurs non NULL, les valeurs de colonne pour chaque paire de lignes de l' employé et de l' emplacement correspondant sont combinées dans une ligne de résultat. Voici à quoi ressemblera le SQL d'une jointure interne:

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

Maintenant, voici à quoi ressemblerait le résultat de l'exécution de SQL: entrez la description de l'image ici

Jointure externe: - Une jointure externe ne nécessite pas que chaque enregistrement des deux tables jointes ait un enregistrement correspondant. La table jointe conserve chaque enregistrement, même s'il n'existe aucun autre enregistrement correspondant. Les jointures externes se subdivisent davantage en jointures externes gauche et jointures externes droite, selon les lignes de la table qui sont conservées (gauche ou droite).

Jointure externe gauche: - Le résultat d'une jointure externe gauche (ou simplement jointure gauche) pour les tables Employé et Emplacement contient toujours tous les enregistrements de la table "gauche" ( Employé ), même si la condition de jointure ne trouve aucun enregistrement correspondant dans le "bon" tableau ( Emplacement ). Voici à quoi ressemblerait le SQL pour une jointure externe gauche, en utilisant les tableaux ci-dessus:

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

Maintenant, voici à quoi ressemblerait le résultat de l'exécution de ce SQL: entrez la description de l'image ici

Jointure externe droite: - Une jointure externe droite (ou jointure droite) ressemble étroitement à une jointure externe gauche, sauf avec le traitement des tableaux inversé. Chaque ligne de la table "droite" ( Emplacement ) apparaîtra dans la table jointe au moins une fois. Si aucune ligne correspondante de la table "gauche" ( Employé ) n'existe, NULL apparaîtra dans les colonnes de Employé pour les enregistrements qui n'ont aucune correspondance dans Emplacement . Voici à quoi ressemble le SQL:

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

En utilisant les tableaux ci-dessus, nous pouvons montrer à quoi ressemblerait l'ensemble de résultats d'une jointure externe droite:

entrez la description de l'image ici

Jointures extérieures complètes: - externes complètes La jointure externe complète ou la jointure complète consiste à conserver les informations non correspondantes en incluant des lignes non correspondantes dans les résultats d'une jointure, utilisez une jointure externe complète. Il inclut toutes les lignes des deux tables, que l'autre table ait ou non une valeur correspondante.

Source de l'image

Manuel de référence MySQL 8.0 - Join Syntax

Opérations Oracle Join

ajitksharma
la source
3
meilleure réponse jusqu'à présent, syntaxe alternative - c'est ce que je cherchais, merci!
Joey
1
Les diagrammes de Venn sont mal étiquetés. Voir mes commentaires sur la question et autres réponses. De plus, la plupart de cette langue est pauvre. Par exemple: "Lorsque le prédicat de jointure est satisfait en faisant correspondre des valeurs non NULL, les valeurs de colonne pour chaque paire de lignes de l'employé et de l'emplacement correspondant sont combinées en une ligne de résultat." Non, pas "Lorsque le prédicat de jointure est satisfait en faisant correspondre des valeurs non NULL". Les valeurs dans les lignes n'ont pas d'importance si la condition dans son ensemble est vraie ou fausse. Certaines valeurs pourraient bien être NULL pour une condition vraie.
philipxy
Bien qu'ils ne soient pas explicitement indiqués, les diagrammes de ce document sont des diagrammes de Venn. Les diagrammes de Venn ne sont pas, en général, la caractérisation mathématique correcte d'une jointure. Je suggère de supprimer les diagrammes de Venn.
Colm Bhandal
@ColmBhandal: suppression des diagrammes de Venn
ajitksharma
Veuillez utiliser du texte, pas des images / liens, pour le texte - y compris les tableaux et les ERD . Utilisez des images uniquement pour ce qui ne peut pas être exprimé sous forme de texte ou pour augmenter le texte. Les images ne peuvent pas être recherchées ou coupées et collées. Inclure une légende / clé et explication avec une image.
philipxy
133

Jointure interne

Récupérez uniquement les lignes correspondantes, c'est-à-dire A intersect B.

Entrez la description de l'image ici

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Jointure externe gauche

Sélectionnez tous les enregistrements de la première table et tous les enregistrements de la deuxième table qui correspondent aux clés jointes.

Entrez la description de l'image ici

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Jointure externe complète

Sélectionnez tous les enregistrements de la deuxième table et tous les enregistrements de la première table qui correspondent aux clés jointes.

Entrez la description de l'image ici

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Références

Tushar Gupta - curioustushar
la source
14
Quel est le nom de l'outil? Je trouve cela intéressant car il montre le nombre de lignes et de diagrammes de
Venn
2
@GrijeshChauhan Oui, mais vous pouvez essayer de l'exécuter avec du vin .
Tushar Gupta - curioustushar
2
Ohh! oui j'ai .. J'ai utilisé SQLyog avec du vin .. il y a aussi PlayOnLinux
Grijesh Chauhan
1
Votre texte n'est pas clair et faux. Les "lignes appariées uniquement" sont des lignes de la jointure croisée de A et B et ce qui est récupéré (une jointure interne B) n'est pas une intersection A mais une intersection (une jointure gauche B) (une jointure droite B). Les lignes "sélectionnées" ne sont pas de A et B, elles sont de A jointure croisée B et de valeurs étendues nulles de lignes de A et B.
philipxy
@ TusharGupta-curioustushar vous devez inclure les "Tables utilisées pour les exemples SQL"
Manuel Jordan
112

En termes simples:

Une jointure interne récupère uniquement les lignes correspondantes.

Alors qu'une jointure externe récupère les lignes correspondantes d'une table et toutes les lignes d'une autre table .... le résultat dépend de celle que vous utilisez:

  • Gauche : lignes correspondantes dans le tableau de droite et toutes les lignes du tableau de gauche

  • Droite : lignes correspondantes dans le tableau de gauche et toutes les lignes du tableau de droite ou

  • Complet : toutes les lignes de tous les tableaux. Peu importe s'il y a correspondance ou non

vidyadhar
la source
1
@nomen Ce n'est pas que cette réponse y répond, mais INNER JOIN est une intersection et FULL OUTER JOIN est l'UNION correspondante si les ensembles / cercles gauche et droit contiennent les lignes (respectivement) de jointure GAUCHE et DROITE. PS Cette réponse n'est pas claire sur les lignes en entrée vs en sortie. Il confond "dans la table gauche / droite" avec "a une partie gauche / droite dans la gauche / droite" et il utilise "ligne correspondante" vs "tous" pour signifier la ligne étendue par ligne à partir d'une autre table vs par null.
philipxy
104

Une jointure interne n'affiche des lignes que s'il existe un enregistrement correspondant de l'autre côté (droit) de la jointure.

Une jointure externe (gauche) affiche des lignes pour chaque enregistrement sur le côté gauche, même s'il n'y a pas de lignes correspondantes de l'autre côté (droit) de la jointure. S'il n'y a pas de ligne correspondante, les colonnes de l'autre côté (droit) afficheront des valeurs NULL.

1800 INFORMATION
la source
82

Les jointures internes nécessitent qu'un enregistrement avec un ID associé existe dans la table jointe.

Les jointures externes renverront des enregistrements pour le côté gauche même si rien n'existe pour le côté droit.

Par exemple, vous avez une table Orders et une table OrderDetails. Ils sont liés par un "OrderID".

Ordres

  • Numéro de commande
  • CustomerName

Détails de la commande

  • OrderDetailID
  • Numéro de commande
  • ProductName
  • Qté
  • Prix

La demande

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

ne renverra que les commandes qui contiennent également quelque chose dans la table OrderDetails.

Si vous le remplacez par EXTERIEUR GAUCHE

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

il renverra alors les enregistrements de la table Orders même s'ils n'ont aucun enregistrement OrderDetails.

Vous pouvez l'utiliser pour trouver des commandes qui n'ont aucun OrderDetails indiquant une commande orpheline possible en ajoutant une clause where comme WHERE OrderDetails.OrderID IS NULL.

Brian Boatright
la source
1
J'apprécie l'exemple simple mais réaliste. J'ai changé une demande comme SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASCà SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC(MySQL) avec succès. Je n'étais pas sûr des conditions supplémentaires, elles se mélangent bien ...
PhiLho
68

En termes simples:

Jointure interne -> Prendre UNIQUEMENT des enregistrements communs des tables parent et enfant OERE la clé primaire de la table parent correspond à la clé étrangère dans la table enfant.

Jointure gauche ->

pseudo code

1.Take All records from left Table
2.for(each record in right table,) {
    if(Records from left & right table matching on primary & foreign key){
       use their values as it is as result of join at the right side for 2nd table.
    } else {
       put value NULL values in that particular record as result of join at the right side for 2nd table.
    }
  }

Jointure droite : Exactement opposée à la jointure gauche. Mettez le nom de la table dans LEFT JOIN à droite dans Right join, vous obtenez la même sortie que LEFT JOIN.

Jointure externe : affiche tous les enregistrements des deux tables No matter what. Si les enregistrements de la table de gauche ne correspondent pas à la table de droite en fonction de la clé Forieign principale, utilisez la valeur NULL comme résultat de la jointure.

Exemple :

Exemple

Supposons maintenant pour 2 tables

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

Ici, la table des employés est la table principale, phone_numbers_employees est la table enfant (elle contient emp_idcomme clé étrangère qui connecte employee.idainsi sa table enfant.)

Jointures internes

Prenez les enregistrements de 2 tables UNIQUEMENT SI la clé primaire de la table des employés (son id) correspond à la clé étrangère de la table enfant phone_numbers_employees (emp_id) .

La requête serait donc:

SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Ici, prenez uniquement les lignes correspondantes sur la clé primaire = clé étrangère comme expliqué ci-dessus. Ici, les lignes non correspondantes sur la clé primaire = clé étrangère sont ignorées en raison de la jointure.

Jointures gauches :

La jointure gauche conserve toutes les lignes de la table de gauche, qu'il existe ou non une ligne correspondant à la table de droite.

SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Jointures externes :

SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Schématiquement, cela ressemble à:

Diagramme

Pratik
la source
4
Le résultat n'a rien à faire (en soi) avec les clés primaires / uniques / candidates et les clés étrangères. Le baviour peut et doit être décrit sans référence à eux. Une jointure croisée est calculée, puis les lignes ne correspondant pas à la condition ON sont filtrées; en outre pour les jointures externes, les lignes filtrées / les lignes sans correspondance sont étendues par des valeurs NULL (par LEFT / RIGHT / FULL et incluses.
philipxy
L'hypothèse que les jointures SQL correspondent toujours aux clés primaires / étrangères conduit à cette mauvaise utilisation des diagrammes de Venn. Veuillez réviser votre réponse en conséquence.
Colm Bhandal
58

Vous utilisez INNER JOINpour renvoyer toutes les lignes des deux tables où il y a une correspondance. ie dans le tableau résultant, toutes les lignes et colonnes auront des valeurs.

Dans OUTER JOIN le tableau résultant peut avoir des colonnes vides. La jointure externe peut être soit LEFTou RIGHT.

LEFT OUTER JOIN renvoie toutes les lignes de la première table, même s'il n'y a aucune correspondance dans la deuxième table.

RIGHT OUTER JOIN renvoie toutes les lignes de la deuxième table, même s'il n'y a aucune correspondance dans la première table.

vijikumar
la source
56

Ceci est une bonne explication pour les jointures

Ceci est une bonne explication schématique pour toutes sortes de jointures

source: http://ssiddique.info/understanding-sql-joins-in-easy-way.html

Raghu K Nair
la source
1
Ce billet n'explique pas clairement comment interpréter ce diagramme. Voir aussi le premier commentaire sur la question et mes autres commentaires sur cette page.
philipxy
54

INNER JOINnécessite qu'il y ait au moins une correspondance dans la comparaison des deux tableaux. Par exemple, le tableau A et le tableau B qui impliquent A ٨ B (A intersection B).

LEFT OUTER JOIN et LEFT JOIN sont les mêmes. Il donne tous les enregistrements correspondants dans les deux tableaux et toutes les possibilités du tableau de gauche.

De même, RIGHT OUTER JOINet RIGHT JOINsont les mêmes. Il donne tous les enregistrements correspondant dans les deux tables et toutes les possibilités de la bonne table.

FULL JOINest la combinaison de LEFT OUTER JOINet RIGHT OUTER JOINsans duplication.

naga
la source
43

La réponse est dans le sens de chacun, donc dans les résultats.

Remarque:
En SQLiteil n'y a pas RIGHT OUTER JOINou FULL OUTER JOIN.
Et aussi MySQLil n'y a pas FULL OUTER JOIN.

Ma réponse est basée sur la note ci-dessus .

Lorsque vous avez deux tables comme celles-ci:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTER JOIN:
Vous pouvez avoir toutes ces données de tables avec CROSS JOINou simplement avec ,comme ceci:

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

INNER JOIN:
Lorsque vous souhaitez ajouter un filtre aux résultats ci-dessus en fonction d'une relation comme table1.id = table2.idvous pouvez utiliser INNER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

LEFT [OUTER] JOIN:
Lorsque vous voulez avoir toutes les lignes d'une des tables dans le résultat ci-dessus - avec la même relation - vous pouvez utiliser LEFT JOIN:
(Pour RIGHT JOIN il suffit de changer la place des tables)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

FULL OUTER JOIN:
Lorsque vous souhaitez également avoir toutes les lignes de l'autre tableau dans vos résultats, vous pouvez utiliser FULL OUTER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

Eh bien, selon vos besoins, vous choisissez chacun qui répond à vos besoins;).

shA.t
la source
Vous pouvez ajouter à votre note qu'il n'y en a pas non plus full outer joindans MySQL.
potashin
35

Jointure interne.

Une jointure combine les lignes de deux tables. Une jointure interne tente de faire correspondre les deux tables en fonction des critères que vous spécifiez dans la requête et ne renvoie que les lignes qui correspondent. Si une ligne de la première table de la jointure correspond à deux lignes de la deuxième table, deux lignes seront renvoyées dans les résultats. S'il y a une ligne dans la première table qui ne correspond pas à une ligne dans la seconde, elle n'est pas renvoyée; de même, s'il y a une ligne dans la deuxième table qui ne correspond pas à une ligne dans la première, elle n'est pas renvoyée.

Jointure externe.

Une jointure gauche tente de trouver une correspondance entre les lignes de la première table et les lignes de la seconde table. S'il ne trouve pas de correspondance, il renverra les colonnes de la première table et laissera les colonnes de la deuxième table vides (null).

Kanwar Singh
la source
28

entrez la description de l'image ici

  • INNER JOINjointure la plus typique pour deux tables ou plus. Il renvoie la correspondance des données à la fois sur la relation ON keykey et forignkey.
  • OUTER JOINest identique à INNER JOIN, mais il inclut également des NULLdonnées sur ResultSet.
    • LEFT JOIN= INNER JOIN+ Données inégalées du tableau de gauche avec Nullcorrespondance sur le tableau de droite.
    • RIGHT JOIN= INNER JOIN+ Données inégalées de la table de droite avec Nullcorrespondance sur la table de gauche.
    • FULL JOIN= INNER JOIN+ Données inégalées sur les tableaux de droite et de gauche avec des Nullcorrespondances.
  • L'auto-jointure n'est pas un mot-clé dans SQL, lorsqu'une table fait référence à des données en soi comme auto-jointure. En utilisant INNER JOINet OUTER JOINnous pouvons écrire des requêtes d'auto-jointure.

Par exemple:

SELECT * 
FROM   tablea a 
       INNER JOIN tableb b 
               ON a.primary_key = b.foreign_key 
       INNER JOIN tablec c 
               ON b.primary_key = c.foreign_key 
Premraj
la source
27

Je ne vois pas beaucoup de détails sur les performances et l'optimiseur dans les autres réponses.

Parfois, il est bon de savoir que INNER JOIN est associatif, ce qui signifie que l'optimiseur a le plus d'options pour jouer avec. Il peut réorganiser l'ordre de jointure pour le rendre plus rapide en conservant le même résultat. L'optimiseur peut utiliser le plus de modes de jointure.

En règle générale, il est recommandé d'utiliser INNER JOINplutôt que les différents types de jointures. (Bien sûr, si cela est possible compte tenu de l'ensemble de résultats escompté.)

Il y a quelques bons exemples et explications ici sur cet étrange comportement associatif:

Lajos Veres
la source
4
Il ne peut pas être une "bonne pratique" d'utiliser un type de jointure sur un autre. La jointure que vous utilisez détermine les données que vous souhaitez. Si vous en utilisez un autre, vous vous trompez. De plus, dans Oracle au moins, cette réponse est complètement fausse. Cela semble complètement faux pour tout et vous n'avez aucune preuve. Avez-vous une preuve?
Ben
1. Je veux dire, essayez d'utiliser. J'ai vu beaucoup de gens utiliser des jointures LEFT OUTER partout sans aucune bonne raison. (Les colonnes jointes n'étaient pas nulles.) Dans ces cas, il serait certainement préférable d'utiliser les jointures INNER. 2. J'ai ajouté un lien expliquant le comportement non associatif mieux que moi.
Lajos Veres
Comme je sais, INNER JOINc'est plus lent que la LEFT JOINplupart du temps, et les gens peuvent utiliser LEFT JOINau lieu d' INNER JOINen ajouter un WHEREpour supprimer les NULLrésultats inattendus ;).
shA.t
Ces commentaires m'ont rendu un peu incertain. Pourquoi pensez-vous que INNERc'est plus lent?
Lajos Veres
Dépend du moteur. jointure gnu, joinkeys, DB2, MySQL. Les pièges de performance abondent, tels que la frappe lâche ou une distribution explicite.
mckenzm
26

Ayant critiqué le diagramme de Venn aux tons rouges très apprécié, j'ai pensé qu'il était juste de publier ma propre tentative.

Bien que la réponse de @Martin Smith soit la meilleure de cette grappe de loin, la sienne ne montre que la colonne clé de chaque table, alors que je pense que les colonnes non clés devraient également être affichées.

Du mieux que j'ai pu faire dans la demi-heure autorisée, je ne pense toujours pas que cela montre adéquatement que les valeurs nulles sont là en raison de l'absence de valeurs clés dans TableBou qui OUTER JOINest en fait une union plutôt qu'une jointure:

entrez la description de l'image ici

un jour
la source
2
La question demande la différence entre les jointures INNER et OUTER cependant, pas nécessairement la jointure externe gauche lol
LearnByReading
@LearnByReading: ma photo de droite est une jointure externe droite, c'est-à-dire remplacer TableA a LEFT OUTER JOIN TableB bparTableB B RIGHT OUTER JOIN TableA a
onedaywhen le
26

L'algorithme précis pour INNER JOIN, LEFT/RIGHT OUTER JOINest le suivant:

  1. Prenez chaque ligne du premier tableau: a
  2. Considérez toutes les lignes du deuxième tableau à côté: (a, b[i])
  3. Évaluez la ON ...clause par rapport à chaque paire:ON( a, b[i] ) = true/false?
    • Lorsque la condition est évaluée à true, renvoyez cette ligne combinée (a, b[i]).
    • Lorsque vous atteignez la fin de la deuxième table sans aucune correspondance, il s'agit Outer Joinalors de renvoyer une paire (virtuelle) en utilisant Nullpour toutes les colonnes de l'autre table: (a, Null)pour la jointure externe GAUCHE ou (Null, b)pour la jointure externe DROITE. Il s'agit de s'assurer que toutes les lignes de la première table existent dans les résultats finaux.

Remarque: la condition spécifiée dans la ONclause peut être n'importe quoi, il n'est pas nécessaire d'utiliser des clés primaires (et vous n'avez pas besoin de toujours faire référence aux colonnes des deux tables)! Par exemple:

Jointure interne vs jointure externe gauche


entrez la description de l'image ici

Remarque: Jointure gauche = jointure externe gauche, jointure droite = jointure externe droite.

S.Serpooshan
la source
20

Définitions les plus simples

Inner Join: renvoie les enregistrements correspondants des deux tables.

Jointure externe complète: renvoie les enregistrements correspondants et sans correspondance des deux tables avec null pour les enregistrements sans correspondance des deux tables .

Jointure externe gauche: renvoie les enregistrements correspondants et non correspondants uniquement à partir du tableau du côté gauche .

Jointure externe droite: renvoie uniquement les enregistrements correspondants et inégalés à partir de la table du côté droit .

En bref

Correspondance + gauche sans correspondance + droite sans correspondance = jointure externe complète

Correspondance + gauche inégalée = jointure externe gauche

Matched + Right Unmatched = Jointure externe droite

Correspondance = jointure interne

Akshay Khale
la source
1
C'est brillant et explique pourquoi la jointure ne fonctionne pas comme prévu pour les index de séries temporelles. Les horodatages distants d'une seconde sont sans égal.
yeliabsalohcin
1
@yeliabsalohcin Vous n'expliquez pas "comme prévu" ici ou "fonctionne" dans votre commentaire sur la question. C'est juste une idée fausse personnelle inexpliquée que vous attendez étrangement des autres. Si vous traitez les mots avec autant de négligence lorsque vous lisez - en interprétant mal une écriture claire et / ou en acceptant une écriture peu claire - que lorsque vous écrivez ici, vous pouvez vous attendre à avoir des idées fausses. En fait, cette réponse comme la plupart ici n'est pas claire et erronée. "Jointure interne: renvoie les enregistrements correspondants des deux tables" est incorrect lorsque les ensembles de colonnes d'entrée diffèrent. Il essaie de dire un certain quelque chose, mais ce n'est pas le cas . (Voir ma réponse.)
philipxy
9

En termes simples,

1. INNER JOIN OU EQUI JOIN: renvoie l'ensemble de résultats qui ne correspond qu'à la condition dans les deux tableaux.

2. OUTER JOIN: renvoie le jeu de résultats de toutes les valeurs des deux tables même s'il existe une correspondance de condition ou non.

3. JOINT GAUCHE: renvoie l'ensemble de résultats de toutes les valeurs du tableau de gauche et uniquement les lignes qui correspondent à la condition du tableau de droite.

4. JOINDRE À DROITE: renvoie l'ensemble de résultats de toutes les valeurs de la table de droite et uniquement les lignes qui correspondent à la condition dans la table de gauche.

5. FULL JOIN: la jointure complète et la jointure externe complète sont identiques.

Anands23
la source
5

Il existe principalement 2 types de JOIN en SQL: [INNER et OUTER]


Exemples

Supposons que vous ayez deux tables, avec une seule colonne chacune, et les données comme suit:

A    B
-    -
1    3
2    4
3    5
4    6
7
8

Notez que (1,2,7,8) sont uniques à A, (3,4) sont communs et (5,6) sont uniques à B.



  • (INTÉRIEUR) REJOIGNEZ :

Le mot clé INNER JOIN sélectionne toutes les lignes des deux tables tant que la condition est remplie. Ce mot-clé créera l'ensemble de résultats en combinant toutes les lignes des deux tables où la condition satisfait, c'est-à-dire que la valeur du champ commun sera la même.

JOINTURE INTERNE

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

Résultat:

a | b
--+--
3 | 3
4 | 4


  • JOINT GAUCHE (EXTÉRIEUR) :

Cette jointure renvoie toutes les lignes de la table sur le côté gauche de la jointure et les lignes correspondantes pour la table sur le côté droit de la jointure. Les lignes pour lesquelles il n'y a pas de ligne correspondante sur le côté droit, le jeu de résultats contiendra null. LEFT JOIN est aussi connu sous le nom de LEFT OUTER JOIN.

JOINT GAUCHE / JOINT EXTERIEUR GAUCHE

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

Résultat:

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4
7 | null
8 | null


  • RIGHT (OUTER) JOIN : renvoie tous les enregistrements de la table de droite et les enregistrements correspondants de la table de gauche

JOINT DROIT / JOINT EXTERNE DROIT

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

Résultat:

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6


  • JOINTURE COMPLÈTE (EXTÉRIEURE) :

    FULL JOIN crée l'ensemble de résultats en combinant le résultat de LEFT JOIN et de RIGHT JOIN. L'ensemble de résultats contiendra toutes les lignes des deux tables. Les lignes pour lesquelles il n'y a pas de correspondance, l'ensemble de résultats contiendra des valeurs NULL.

FULL JOIN / FULL OUTER JOIN

select * from a FULL OUTER JOIN b on a.a = b.b;

Résultat:

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5
   7 | null
   8 | null
Mayur
la source
1
Les diagrammes de Venn ne suffisent pas pour décrire les jointures SQL dans le cas général. Les jointures SQL ne doivent pas nécessairement faire correspondre les lignes entre les tables une par une, par exemple en utilisant une clé étrangère par rapport à une clé primaire.
Colm Bhandal
Comment joindre 2 tables sans faire correspondre la ligne? Vous devez avoir besoin d'une clé primaire ou étrangère de colonne ou d'un champ commun pour pouvoir effectuer la jointure. Je me demande pourquoi vous avez rejeté cette réponse. Et le diagramme de Venn est la source pour expliquer comment fonctionne SQL JOIN. Avez-vous de meilleurs exemples pour représenter les jointures? Si ce n'est pas le cas, veuillez le voter, afin que les gens obtiennent de meilleures solutions. Je vous remercie.
Mayur
Vous êtes celui qui met les diagrammes dans le message. Quelle est la légende des diagrammes? - Quels sont les éléments de chaque ensemble? Et qu'en est-il du fait que les tables sont des sacs et non des sets? Tu ne dis pas. Une chose dont ils ne sont pas des ensembles est des rangées A et B par les étiquettes. Voir mes commentaires sur les messages sur cette page. Ce message répète aveuglément un mauvais usage vu ailleurs mais non compris ou remis en question. De plus, les choses que vous dites dans le texte ici ne sont pas claires et erronées. De plus, cela n'ajoute rien aux nombreuses réponses déjà présentes. (Même si presque tous sont assez pauvres.) PS Veuillez clarifier via des modifications, pas des commentaires.
philipxy
Les FK ne sont pas nécessaires pour rejoindre ou interroger. 2 tables peuvent être jointes à n'importe quelle condition impliquant leurs colonnes et quelles que soient les contraintes, déclencheurs ou assertions.
philipxy
3
  • Jointure interne - Une jointure interne utilisant l'une des requêtes équivalentes donne l'intersection des deux tables , c'est-à-dire les deux lignes qu'elles ont en commun.

  • Jointure externe gauche - Une jointure externe gauche donnera toutes les lignes dans A, plus toutes les lignes communes dans B.

  • Jointure externe complète - Une jointure externe complète vous donnera l'union de A et B, c'est-à-dire toutes les lignes dans A et toutes les lignes dans B. Si quelque chose dans A n'a pas de donnée correspondante dans B, alors la partie B est null et vice versa

Sandesh
la source
1
C'est à la fois faux et peu clair. La jointure n'est pas une intersection sauf si les tables ont les mêmes colonnes. Les jointures externes n'ont pas de lignes de A ou B sauf si elles ont les mêmes colonnes, auquel cas il n'y a pas de null ajoutés. Vous essayez de dire quelque chose, mais vous ne le dites pas. Vous n'expliquez pas correctement ou clairement.
philipxy
@philipxy: pas d'accord sur votre déclaration. Join is not an intersection unless the tables have the same columnsNon. Vous pouvez joindre toutes les colonnes de votre choix et si la valeur correspond, elles se rejoindront.
SuicideSheep
Ce commentaire n'est pas aussi clair que votre réponse. (Je suppose que vous pensez peut-être à quelque chose comme, l'ensemble des valeurs de sous-lignes pour les colonnes communes du résultat est l'intersection des ensembles de valeurs de sous-lignes pour les colonnes communes de chacune des entrées; mais ce n'est pas ce que vous avez écrit. Vous ne sont pas claires.)
philipxy
Ce que je voulais dire, c'est que la jointure n'est qu'une intersection d'entrées lorsqu'il s'agit d'une jointure interne naturelle d'entrées avec les mêmes colonnes. Vous utilisez à tort les mots «intersection» et «union».
philipxy
3

1. Jointure interne: également appelée jointure. Il renvoie les lignes présentes dans le tableau de gauche et le tableau de droite uniquement s'il existe une correspondance . Sinon, il ne renvoie aucun enregistrement.

Exemple:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

sortie1

2. Jointure externe complète: également appelée jointure complète. Il renvoie toutes les lignes présentes à la fois dans le tableau de gauche et dans le tableau de droite.

Exemple:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

sortie2

3. Jointure gauche externe: ou simplement appelée jointure gauche. Il renvoie toutes les lignes présentes dans le tableau de gauche et les lignes correspondantes du tableau de droite (le cas échéant).

4. Jointure externe droite: également appelée jointure droite. Il renvoie les lignes correspondantes de la table de gauche (le cas échéant) et toutes les lignes présentes dans la table de droite.

rejoint

Avantages des jointures

  1. S'exécute plus rapidement.
Laxmi
la source
2
Cela n'est correct que lorsque les tables ont le même jeu de colonnes. (Il confond la jointure interne avec l'intersection et la jointure complète avec l'union.) La "correspondance" n'est pas non plus définie. Lisez mes autres commentaires.
philipxy
2

Considérez ci-dessous 2 tableaux:

EMP

empid   name    dept_id salary
1       Rob     1       100
2       Mark    1       300
3       John    2       100
4       Mary    2       300
5       Bill    3       700
6       Jose    6       400

département

deptid  name
1       IT
2       Accounts
3       Security
4       HR
5       R&D

Jointure interne:

Généralement écrit comme simplement JOIN dans des requêtes SQL. Il renvoie uniquement les enregistrements correspondants entre les tables.

Découvrez tous les employés et les noms de leurs départements:

Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security

Comme vous le voyez ci-dessus, Josen'est pas imprimé à partir d' EMP dans la sortie car son dept_id 6ne trouve pas de correspondance dans la table Department. De même, HRet les R&Dlignes ne sont pas imprimées du département table comme ils ne trouvaient pas un match dans le tableau Emp.

Ainsi, INNER JOIN ou simplement JOIN, renvoie uniquement les lignes correspondantes.

JOINT GAUCHE :

Cela renvoie tous les enregistrements de la table LEFT et uniquement les enregistrements correspondants de la table RIGHT.

Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security
6       Jose    

Ainsi, si vous observez la sortie ci-dessus, tous les enregistrements de la table LEFT (Emp) sont imprimés avec uniquement les enregistrements correspondants de la table RIGHT.

HRet les R&Dlignes ne sont pas imprimées à partir de la table Department car elles n'ont pas trouvé de correspondance dans la table Emp sur dept_id.

Ainsi, LEFT JOIN renvoie TOUTES les lignes de la table Left et uniquement les lignes correspondantes de la table RIGHT.

Vous pouvez également consulter DEMO ici .

Mayank Porwal
la source
2

L'idée générale

Veuillez consulter la réponse de Martin Smith pour de meilleures illustrations et explications des différentes jointures, y compris et surtout les différences entre FULL OUTER JOIN, RIGHT OUTER JOINet LEFT OUTER JOIN.

Ces deux tableaux constituent une base pour la représentation des JOINs ci-dessous:

Base

CROSS JOIN

CrossJoin

SELECT *
  FROM citizen
 CROSS JOIN postalcode

Le résultat sera les produits cartésiens de toutes les combinaisons. Aucune JOINcondition requise:

CrossJoinResult

JOINTURE INTERNE

INNER JOIN est la même chose que simplement: JOIN

Jointure interne

SELECT *
  FROM citizen    c
  JOIN postalcode p ON c.postal = p.postal

Le résultat sera des combinaisons qui satisfont à la JOINcondition requise :

InnerJoinResult

JOINTURE EXTERNE GAUCHE

LEFT OUTER JOIN est le même que LEFT JOIN

Joint gauche

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal

Le résultat sera tout, citizenmême s'il n'y a pas de correspondance postalcode. Encore une fois, une JOINcondition est requise:

LeftJoinResult

Données pour jouer

Tous les exemples ont été exécutés sur un Oracle 18c. Ils sont disponibles sur dbfiddle.uk, d'proviennent également les captures d'écran des tableaux.

CREATE TABLE citizen (id      NUMBER,
                      name    VARCHAR2(20),
                      postal  NUMBER,  -- <-- could do with a redesign to postalcode.id instead.
                      leader  NUMBER);

CREATE TABLE postalcode (id      NUMBER,
                         postal  NUMBER,
                         city    VARCHAR2(20),
                         area    VARCHAR2(20));

INSERT INTO citizen (id, name, postal, leader)
              SELECT 1, 'Smith', 2200,  null FROM DUAL
        UNION SELECT 2, 'Green', 31006, 1    FROM DUAL
        UNION SELECT 3, 'Jensen', 623,  1    FROM DUAL;

INSERT INTO postalcode (id, postal, city, area)
                 SELECT 1, 2200,     'BigCity',         'Geancy'  FROM DUAL
           UNION SELECT 2, 31006,    'SmallTown',       'Snizkim' FROM DUAL
           UNION SELECT 3, 31006,    'Settlement',      'Moon'    FROM DUAL  -- <-- Uuh-uhh.
           UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space'   FROM DUAL;

Limites floues lors de la lecture avec JOINetWHERE

CROSS JOIN

CROSS JOINrésultant en lignes comme l'idée générale / INNER JOIN:

SELECT *
  FROM citizen          c
  CROSS JOIN postalcode p
 WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows

L'utilisation CROSS JOINpour obtenir le résultat d'un LEFT OUTER JOINrequiert des astuces comme l'ajout NULLconsécutif. C'est omis.

JOINTURE INTERNE

INNER JOINdevient un produit cartésien. C'est la même chose que The General Idea / CROSS JOIN:

SELECT *
  FROM citizen    c
  JOIN postalcode p ON 1 = 1  -- < -- The ON condition makes it a CROSS JOIN

C'est là que la jointure interne peut vraiment être vue comme la jointure croisée avec des résultats ne correspondant pas à la condition supprimée. Ici, aucune des lignes résultantes n'est supprimée.

Utiliser INNER JOINpour obtenir le résultat d'un LEFT OUTER JOINnécessite également des astuces. C'est omis.

JOINTURE EXTERNE GAUCHE

LEFT JOINrésulte en lignes comme l'idée générale / CROSS JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN

LEFT JOINrésulte en lignes comme l'idée générale / INNER JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal
 WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode

Les problèmes avec le diagramme de Venn

Une recherche d'image sur Internet sur "sql join cross inner inner" montrera une multitude de diagrammes de Venn. J'en avais une copie imprimée sur mon bureau. Mais il y a des problèmes avec la représentation.

Le diagramme de Venn est excellent pour la théorie des ensembles, où un élément peut être dans l'un ou les deux ensembles. Mais pour les bases de données, un élément dans un "ensemble" me semble être une ligne dans une table, et donc pas également présent dans d'autres tables. Il n'y a rien de tel qu'une ligne présente dans plusieurs tables. Une ligne est unique à la table.

Les auto-jointures sont un cas d'angle où chaque élément est en fait le même dans les deux ensembles. Mais ce n'est toujours pas exempt des problèmes ci-dessous.

L'ensemble Areprésente l'ensemble à gauche (le citizentableau) et l'ensemble Best l'ensemble à droite (le postalcodetableau) dans la discussion ci-dessous.

CROSS JOIN

Chaque élément des deux ensembles correspond à chaque élément de l'autre ensemble, ce qui signifie que nous avons besoin de la Aquantité de tous les Béléments et de la Bquantité de tous les Aéléments pour représenter correctement ce produit cartésien. La théorie des ensembles n'est pas faite pour plusieurs éléments identiques dans un ensemble, donc je trouve que les diagrammes de Venn pour le représenter correctement sont peu pratiques / impossibles. Il ne semble pas queUNION convenir.

Les rangées sont distinctes. Il UNIONs'agit d'un total de 7 lignes. Mais ils sont incompatibles pour un SQLensemble de résultats commun . Et ce n'est pas du tout ainsi que CROSS JOINfonctionne:

CrossJoinUnion1

Essayer de le représenter comme ceci:

CrossJoinUnion2Crossing

..mais maintenant ça ressemble à un INTERSECTION, ce qui n'est certainement pas le cas . De plus, il n'y a aucun élément dans INTERSECTIONqui se trouve réellement dans l'un des deux ensembles distincts. Cependant, cela ressemble beaucoup aux résultats consultables similaires à ceci:

CrossJoinUnionUnion3

Pour référence, un résultat de recherche pour CROSS JOINs peut être vu sur Tutorialgateway . Le INTERSECTION, tout comme celui-ci, est vide.

JOINTURE INTERNE

La valeur d'un élément dépend de la JOINcondition. Il est possible de représenter cela sous la condition que chaque ligne devienne unique à cette condition. La signification id=xn'est vraie que pour une ligne. Une fois qu'une ligne de table A( citizen) correspond à plusieurs lignes de table B( postalcode) sous la JOINcondition, le résultat présente les mêmes problèmes que CROSS JOIN: La ligne doit être représentée plusieurs fois, et la théorie des ensembles n'est pas vraiment faite pour cela. Sous la condition d'unicité, le diagramme peut cependant fonctionner, mais gardez à l'esprit que la JOINcondition détermine le placement d'un élément dans le diagramme. En regardant uniquement les valeurs de la JOINcondition avec le reste de la ligne juste pour la balade:

InnerJoinIntersection - Rempli

Cette représentation s'effondre complètement lors de l'utilisation d'un INNER JOINavec une ON 1 = 1condition qui en fait un CROSS JOIN.

Avec un self- JOIN, les lignes sont en fait des éléments identitaires dans les deux tables, mais représentant les tables comme les deux Aet Bn'est pas très approprié. Par exemple , un auto commun JOINcondition qui rend un élément Aà faire correspondre un autre élément B est ON A.parent = B.child, ce qui rend la correspondance d' Aà Bdes éléments séparés. D'après les exemples qui SQLressembleraient à ceci:

SELECT *
  FROM citizen c1
  JOIN citizen c2 ON c1.id = c2.leader

SelfJoinResult

Ce qui signifie que Smith est le leader de Green et de Jensen.

JOINT EXTERIEUR

Encore une fois, les problèmes commencent lorsqu'une ligne a plusieurs correspondances avec les lignes de l'autre table. Ceci est encore plus compliqué parce que le OUTER JOINpeut correspondre à l'ensemble vide. Mais dans la théorie des ensembles, l'union d'un ensemble Cet d'un ensemble vide est toujours juste C. L'ensemble vide n'ajoute rien. La représentation de ceci LEFT OUTER JOINmontre généralement tout Apour illustrer que les lignes Asont sélectionnées indépendamment de la présence ou non d'une correspondance B. Les "éléments correspondants" ont cependant les mêmes problèmes que l'illustration ci-dessus. Ils dépendent de la condition. Et l'ensemble vide semble avoir erré vers A:

LeftJoinIntersection - Rempli

Clause WHERE - sens

Trouver toutes les lignes d'un CROSS JOINavec Smith et le code postal sur la Lune:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   AND p.area = 'Moon';

Où - résultat

Maintenant, le diagramme de Venn n'est pas utilisé pour refléter le JOIN. Il est utilisé uniquement pour la WHEREclause:

Où

..et cela a du sens.

Quand INTERSECT et UNION ont du sens

COUPER

Comme expliqué, ce INNER JOINn'est pas vraiment un INTERSECT. Cependant, INTERSECTs peut être utilisé sur les résultats de requêtes distinctes. Ici, un diagramme de Venn est logique, car les éléments des requêtes distinctes sont en fait des lignes qui appartiennent à l'un des résultats ou aux deux. Intersect ne retournera évidemment que les résultats là où la ligne est présente dans les deux requêtes. Cela SQLse traduira par la même ligne que celle ci-dessus WHERE, et le diagramme de Venn sera également le même:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
INTERSECT
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

SYNDICAT

Un OUTER JOINn'est pas un UNION. Cependant, UNIONtravaillez dans les mêmes conditions que INTERSECT, ce qui entraîne un retour de tous les résultats combinant les deux SELECTs:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
UNION
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

ce qui équivaut à:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   OR p.area = 'Moon';

..et donne le résultat:

Union - Résultat

Ici aussi, un diagramme de Venn est logique:

SYNDICAT

Quand cela ne s'applique pas

Une note importante est que ceux-ci ne fonctionnent que lorsque la structure des résultats des deux SELECT est la même, permettant une comparaison ou une union. Les résultats de ces deux ne permettront pas que:

SELECT *
  FROM citizen
 WHERE name = 'Smith'
SELECT *
  FROM postalcode
 WHERE area = 'Moon';

..essayer de combiner les résultats avec UNIONdonne un

ORA-01790: expression must have same datatype as corresponding expression

Pour plus d'intérêt, lisez Dire NON aux diagrammes Venn lors de l'explication des jointures et des jointures sql en tant que diagramme venn . Les deux couvrent également EXCEPT.

Scratte
la source
1

Il y a beaucoup de bonnes réponses ici avec des exemples d' algèbre relationnelle très précis . Voici une réponse très simplifiée qui pourrait être utile pour les codeurs amateurs ou novices avec des dilemmes de codage SQL.

Fondamentalement, le plus souvent, les requêtes JOINse résument à deux cas:

Pour un SELECTsous - ensemble de données A:

  • utiliser INNER JOINlorsque les données connexes que Bvous recherchez DOIVENT exister par conception de base de données;
  • utiliser LEFT JOINlorsque les données connexes que Bvous recherchez MIGHT ou RISQUENT DE NE PAS existe par la conception de base de données.
ForguesR
la source
1

La différence entre inner joinet outer joinest la suivante:

  1. Inner joinest une jointure qui combine des tables basées sur des tuples correspondants, alors que outer joinest une jointure qui combine une table basée sur des tuples correspondants et inégalés.
  2. Inner joinfusionne les lignes correspondantes de deux tables dans lesquelles les lignes sans correspondance sont omises, tandis que les outer joinlignes de fusion de deux tables et les lignes sans correspondance sont remplies avec une valeur nulle.
  3. Inner joinest comme une opération d'intersection, alors que outer joinc'est comme une opération d'union.
  4. Inner joinest deux types, alors qu'il outer joiny en a trois types.
  5. outer joinest plus rapide que inner join.
rashedcs
la source
1
Un résultat de jointure externe est le même que la jointure interne, mais plus quelques lignes supplémentaires, donc je ne sais pas pourquoi vous pensez que la jointure externe serait plus rapide. Quels sont également ces "deux types" de jointure interne? Je suppose que vous faites référence à plein, à gauche et à droite pour l'extérieur?
Martin Smith
1
@ M.achaibou Veuillez ne pas apporter de modifications qui apportent des changements de format inutiles. Les noms des opérateurs ne sont pas du code sauf s'ils sont utilisés dans le code. Veuillez ne pas modifier la signification du message, postez un commentaire à l'auteur. Si vous n'avez pas de représentant, attendez. Il arrive que l'affiche approuve cela, mais ne faites pas de telles modifications. PS La jointure externe n'est pas plus rapide que la jointure interne.
philipxy