Aussi comment faire LEFT JOIN
, RIGHT JOIN
et FULL JOIN
dans tout ça?
Aussi comment faire LEFT JOIN
, RIGHT JOIN
et FULL JOIN
dans tout ça?
Réponses:
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
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.
on
clause par rapport à toutes les lignes de l'étape 1 en conservant celles où le prédicat est évalué.true
(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.
Tableaux source
Commencez d'abord par un CROSS JOIN
(produit cartésien AKA). Cela n'a pas de ON
clause et renvoie simplement chaque combinaison de lignes des deux tables.
SÉLECTIONNEZ A.Couleur, B.COLORE À PARTIR D'UNE CROIX JOIGNEZ B
Les jointures internes et externes ont un prédicat de clause "ON".
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.
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.
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.
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 NULL
valeurs pour le colonnes de droite.
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 NULL
test qui ne soit pas annulable ou pour laquelle la condition de jointure garantit que toutes les NULL
valeurs seront exclues pour que ce modèle fonctionne correctement et éviter de simplement ramener des lignes qui se trouvent avoir une NULL
valeur pour cela. en plus des lignes non appariées.
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.
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.
Aucune ligne de la jointure croisée ne correspond au 1=0
pré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é.
Avec une modification mineure de la requête précédente, on pourrait simuler l'une UNION ALL
des deux tables.
Notez que la WHERE
clause (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 ...
... 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.
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,
Découvrez ces exemples en direct sur SQLFiddle.com .
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:
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:
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:
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:
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.
Récupérez uniquement les lignes correspondantes, c'est-à-dire A intersect B
.
SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
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.
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
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.
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
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
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.
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
Détails de la commande
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
.
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 ...
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 :
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_id
comme clé étrangère qui connecte employee.id
ainsi 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 à:
Vous utilisez INNER JOIN
pour 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 LEFT
ou 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.
Ceci est une bonne explication schématique pour toutes sortes de jointures
source: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
INNER JOIN
né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 JOIN
et RIGHT JOIN
sont les mêmes. Il donne tous les enregistrements correspondant dans les deux tables et toutes les possibilités de la bonne table.
FULL JOIN
est la combinaison de LEFT OUTER JOIN
et RIGHT OUTER JOIN
sans duplication.
La réponse est dans le sens de chacun, donc dans les résultats.
Remarque:
EnSQLite
il n'y a pasRIGHT OUTER JOIN
ouFULL OUTER JOIN
.
Et aussiMySQL
il n'y a pasFULL 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 JOIN
ou 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.id
vous 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;).
full outer join
dans MySQL.
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).
INNER JOIN
jointure 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 JOIN
est identique à INNER JOIN
, mais il inclut également des NULL
données sur ResultSet.
LEFT JOIN
= INNER JOIN
+ Données inégalées du tableau de gauche avec Null
correspondance sur le tableau de droite.RIGHT JOIN
= INNER JOIN
+ Données inégalées de la table de droite avec Null
correspondance sur la table de gauche.FULL JOIN
= INNER JOIN
+ Données inégalées sur les tableaux de droite et de gauche avec des Null
correspondances.INNER JOIN
et OUTER JOIN
nous 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
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 JOIN
plutô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:
INNER JOIN
c'est plus lent que la LEFT JOIN
plupart du temps, et les gens peuvent utiliser LEFT JOIN
au lieu d' INNER JOIN
en ajouter un WHERE
pour supprimer les NULL
résultats inattendus ;).
INNER
c'est plus lent?
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 TableB
ou qui OUTER JOIN
est en fait une union plutôt qu'une jointure:
TableA a LEFT OUTER JOIN TableB b
parTableB B RIGHT OUTER JOIN TableA a
L'algorithme précis pour INNER JOIN
, LEFT/RIGHT OUTER JOIN
est le suivant:
a
(a, b[i])
ON ...
clause par rapport à chaque paire:ON( a, b[i] ) = true/false?
true
, renvoyez cette ligne combinée (a, b[i])
.Outer Join
alors de renvoyer une paire (virtuelle) en utilisant Null
pour 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 ON
clause 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:
... ON T1.title = T2.title AND T1.version < T2.version
(=> voir cet article comme exemple d'utilisation: sélectionnez uniquement les lignes avec une valeur maximale dans une colonne )... ON T1.y IS NULL
... ON 1 = 0
(juste comme échantillon)Remarque: Jointure gauche = jointure externe gauche, jointure droite = jointure externe droite.
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
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.
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.
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.
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
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
.
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
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.
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
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
Join is not an intersection unless the tables have the same columns
Non. Vous pouvez joindre toutes les colonnes de votre choix et si la valeur correspond, elles se rejoindront.
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
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
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.
Avantages des jointures
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
Généralement écrit comme simplement JOIN dans des requêtes SQL. Il renvoie uniquement les enregistrements correspondants entre les tables.
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, Jose
n'est pas imprimé à partir d' EMP dans la sortie car son dept_id 6
ne trouve pas de correspondance dans la table Department. De même, HR
et les R&D
lignes 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.
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.
HR
et les R&D
lignes 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 .
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 JOIN
et LEFT OUTER JOIN
.
Ces deux tableaux constituent une base pour la représentation des JOIN
s ci-dessous:
SELECT *
FROM citizen
CROSS JOIN postalcode
Le résultat sera les produits cartésiens de toutes les combinaisons. Aucune JOIN
condition requise:
INNER JOIN
est la même chose que simplement: JOIN
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
Le résultat sera des combinaisons qui satisfont à la JOIN
condition requise :
LEFT OUTER JOIN
est le même que LEFT JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
Le résultat sera tout, citizen
même s'il n'y a pas de correspondance postalcode
. Encore une fois, une JOIN
condition est requise:
Tous les exemples ont été exécutés sur un Oracle 18c. Ils sont disponibles sur dbfiddle.uk, d' où 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;
JOIN
etWHERE
CROSS JOIN
ré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 JOIN
pour obtenir le résultat d'un LEFT OUTER JOIN
requiert des astuces comme l'ajout NULL
consécutif. C'est omis.
INNER JOIN
devient 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 JOIN
pour obtenir le résultat d'un LEFT OUTER JOIN
nécessite également des astuces. C'est omis.
LEFT JOIN
ré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 JOIN
ré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
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 A
représente l'ensemble à gauche (le citizen
tableau) et l'ensemble B
est l'ensemble à droite (le postalcode
tableau) dans la discussion ci-dessous.
Chaque élément des deux ensembles correspond à chaque élément de l'autre ensemble, ce qui signifie que nous avons besoin de la A
quantité de tous les B
éléments et de la B
quantité 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 UNION
s'agit d'un total de 7 lignes. Mais ils sont incompatibles pour un SQL
ensemble de résultats commun . Et ce n'est pas du tout ainsi que CROSS JOIN
fonctionne:
Essayer de le représenter comme ceci:
..mais maintenant ça ressemble à un INTERSECTION
, ce qui n'est certainement pas le cas . De plus, il n'y a aucun élément dans INTERSECTION
qui se trouve réellement dans l'un des deux ensembles distincts. Cependant, cela ressemble beaucoup aux résultats consultables similaires à ceci:
Pour référence, un résultat de recherche pour CROSS JOIN
s peut être vu sur Tutorialgateway . Le INTERSECTION
, tout comme celui-ci, est vide.
La valeur d'un élément dépend de la JOIN
condition. Il est possible de représenter cela sous la condition que chaque ligne devienne unique à cette condition. La signification id=x
n'est vraie que pour une ligne. Une fois qu'une ligne de table A
( citizen
) correspond à plusieurs lignes de table B
( postalcode
) sous la JOIN
condition, 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 JOIN
condition détermine le placement d'un élément dans le diagramme. En regardant uniquement les valeurs de la JOIN
condition avec le reste de la ligne juste pour la balade:
Cette représentation s'effondre complètement lors de l'utilisation d'un INNER JOIN
avec une ON 1 = 1
condition 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 A
et B
n'est pas très approprié. Par exemple , un auto commun JOIN
condition 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
à B
des éléments séparés. D'après les exemples qui SQL
ressembleraient à ceci:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
Ce qui signifie que Smith est le leader de Green et de Jensen.
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 JOIN
peut correspondre à l'ensemble vide. Mais dans la théorie des ensembles, l'union d'un ensemble C
et d'un ensemble vide est toujours juste C
. L'ensemble vide n'ajoute rien. La représentation de ceci LEFT OUTER JOIN
montre généralement tout A
pour illustrer que les lignes A
sont 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
:
Trouver toutes les lignes d'un CROSS JOIN
avec Smith et le code postal sur la Lune:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
Maintenant, le diagramme de Venn n'est pas utilisé pour refléter le JOIN
. Il est utilisé uniquement pour la WHERE
clause:
..et cela a du sens.
Comme expliqué, ce INNER JOIN
n'est pas vraiment un INTERSECT
. Cependant, INTERSECT
s 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 SQL
se 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';
Un OUTER JOIN
n'est pas un UNION
. Cependant, UNION
travaillez dans les mêmes conditions que INTERSECT
, ce qui entraîne un retour de tous les résultats combinant les deux SELECT
s:
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:
Ici aussi, un diagramme de Venn est logique:
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 UNION
donne 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
.
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 JOIN
se résument à deux cas:
Pour un SELECT
sous - ensemble de données A
:
INNER JOIN
lorsque les données connexes que B
vous recherchez DOIVENT exister par conception de base de données;LEFT JOIN
lorsque les données connexes que B
vous recherchez MIGHT ou RISQUENT DE NE PAS existe par la conception de base de données.La différence entre inner join
et outer join
est la suivante:
Inner join
est une jointure qui combine des tables basées sur des tuples correspondants, alors que outer join
est une jointure qui combine une table basée sur des tuples correspondants et inégalés.Inner join
fusionne les lignes correspondantes de deux tables dans lesquelles les lignes sans correspondance sont omises, tandis que les outer join
lignes de fusion de deux tables et les lignes sans correspondance sont remplies avec une valeur nulle.Inner join
est comme une opération d'intersection, alors que outer join
c'est comme une opération d'union.Inner join
est deux types, alors qu'il outer join
y en a trois types.outer join
est plus rapide que inner join
.