Les jointures @avi gauche et droite sont similaires, si vous n'êtes pas dérangé par la table principale sur laquelle la jointure est basée.
Anup
2
@philipxy: C'est une définition bizarre (même si vous avez raison). Mais je préfère aller dans l'autre sens et commencer par une jointure croisée puis «construire» une jointure intérieure par-dessus. Après tout, le simple concept de jointure croisée invalide ces visualisations du diagramme de Venn informelles et inexactes ...
Lukas Eder
1
Ces images semblent impliquer que l'union est la même que la jointure externe complète et l'intersection est la même que la jointure interne qui n'est pas correcte pour autant que je sache.
mightyWOZ
1
@DevDave, car contrairement à la croyance populaire - une image ne vaut pas mille mots. Voir la réponse suivante.
hyankov
248
Qu'est-ce que c'est SQL JOIN?
SQL JOIN est une méthode pour récupérer des données de deux ou plusieurs tables de base de données.
Dans ce type de JOIN, nous obtenons tous les enregistrements qui correspondent à la condition dans les deux tables, et les enregistrements dans les deux tables qui ne correspondent pas ne sont pas signalés.
En d'autres termes, INNER JOINest basé sur le seul fait que: SEULEMENT les entrées correspondantes dans les DEUX tableaux DEVRAIENT être listées.
Notez que JOINsans d' autres JOINmots - clés (comme INNER, OUTER, LEFT, etc.) est un INNER JOIN. En d'autres termes, JOINest un sucre syntaxique pour INNER JOIN(voir: Différence entre JOIN et INNER JOIN ).
2. JOINT EXTERIEUR:
OUTER JOIN récupère
Soit, les lignes correspondantes d'une table et toutes les lignes de l'autre table Ou, toutes les lignes de toutes les tables (peu importe qu'il y ait ou non une correspondance).
Il existe trois types de jointure externe:
2.1 LEFT OUTER JOIN ou LEFT JOIN
Cette jointure renvoie toutes les lignes de la table de gauche conjointement avec les lignes correspondantes de la table de droite. S'il n'y a aucune colonne correspondant dans le tableau de droite, il renvoie des NULLvaleurs.
2.2 JOINT EXTERIEUR DROIT ou JOINT DROIT
Cela JOINrenvoie toutes les lignes de la table de droite en conjonction avec les lignes correspondantes de la table de gauche. S'il n'y a aucune colonne correspondant dans le tableau de gauche, il renvoie des NULLvaleurs.
2.3 FULL OUTER JOIN ou FULL JOIN
Cela JOINcombine LEFT OUTER JOINet RIGHT OUTER JOIN. Il renvoie des lignes de l'une ou l'autre table lorsque les conditions sont remplies et renvoie une NULLvaleur en l'absence de correspondance.
En d'autres termes, OUTER JOINest basé sur le fait que: UNIQUEMENT les entrées correspondantes dans UNE des tables (DROITE ou GAUCHE) ou LES DEUX tables (COMPLÈTE) DEVRAIENT être répertoriées.
Note that `OUTERJOIN`is a loosened form of`INNERJOIN`.
3. JOINT NATUREL:
Il est basé sur les deux conditions:
l' JOINest sur toutes les colonnes portant le même nom pour l'égalité.
Supprime les colonnes en double du résultat.
Cela semble être de nature plus théorique et en conséquence (probablement) la plupart des SGBD ne prennent même pas la peine de le supporter.
4. CROSS JOIN:
C'est le produit cartésien des deux tables concernées. Le résultat d'une CROSS JOINvolonté n'a pas de sens dans la plupart des situations. De plus, nous n'en aurons pas du tout besoin (ou en avons le moins besoin, pour être précis).
5. AUTO-JOINDRE:
Il n'est pas une forme différente de JOIN, mais plutôt un JOIN( INNER, OUTER, etc.) d'une table à elle - même.
JOINs basés sur les opérateurs
Selon l'opérateur utilisé pour une JOINclause, il peut y avoir deux types de JOINs. Elles sont
Equi JOIN
Theta JOIN
1. Equi JOIN:
Pour tout le JOINtype ( INNER, OUTER, etc.), si nous utilisons uniquement l'opérateur d'égalité (=), alors nous disons que l' JOINest un EQUI JOIN.
2. Theta JOIN:
C'est la même chose EQUI JOINmais cela permet à tous les autres opérateurs comme>, <,> = etc.
Beaucoup considèrent les deux EQUI JOINet Theta comme JOINsimilaires INNER, OUTER
etc. JOINs. Mais je crois fermement que c'est une erreur et rend les idées vagues. Parce que INNER JOIN, OUTER JOINetc sont tous reliés aux tables et leurs données alors que EQUI JOINet THETA JOINne sont reliés avec les opérateurs que nous utilisons dans l'ancien.
Encore une fois, nombreux sont ceux qui considèrent NATURAL JOINcomme une sorte de "particulier" EQUI JOIN. En fait, c'est vrai, à cause de la première condition que j'ai mentionnée NATURAL JOIN. Cependant, nous n'avons pas à restreindre cela simplement au NATURAL JOINseul. INNER JOINs, OUTER JOINs etc pourrait aussi être un EQUI JOIN.
Il y a relativement nouveau LATERAL JOIN .. SELECT * FROM r1, LATERAL fx (r1)
Pavel Stehule
13
Bien que cela semble raisonnable, je ne pense pas que les réponses «qu'est-ce qu'une jointure SQL» transmettent des informations utiles. La réponse dans son ensemble est une référence écrite pour les personnes qui comprennent déjà les jointures, pas pour les types de personnes qui posent ces questions. Il omet également les références, à la fois pour étayer ses allégations (comme il convient en cas de réponse autoritaire) et pour fournir des explications supplémentaires via des ressources externes. Si vous essayez d'écrire une réponse faisant autorité pour lier de nouveaux utilisateurs SQL à, il peut être utile de remplir un peu les blancs, en particulier la partie "qu'est-ce qu'une jointure".
Craig Ringer
pouvez-vous donner quelques exemples?
avi
67
Définition:
JOINS est un moyen d'interroger les données qui se sont combinées à partir de plusieurs tables simultanément.
Types de JOINS:
Concernant le SGBDR, il existe 5 types de jointures:
Equi-Join: combine les enregistrements communs de deux tables en fonction de la condition d'égalité. Techniquement, la jointure a été effectuée en utilisant l'opérateur d'égalité (=) pour comparer les valeurs de la clé primaire d'une table et les valeurs de la clé étrangère d'une autre table, donc le jeu de résultats comprend les enregistrements communs (correspondants) des deux tables. Pour la mise en œuvre, voir INNER-JOIN.
Natural-Join: Il s'agit d'une version améliorée d'Equi-Join, dans laquelle l'opération SELECT omet la colonne en double. Pour la mise en œuvre, voir INNER-JOIN
Non-Equi-Join: c'est l'inverse de Equi-join où la condition de jointure utilise des opérateurs différents de l'égalité (=) par exemple,! =, <=,> =,>, <Ou BETWEEN etc. Pour la mise en œuvre, voir INNER-JOIN.
Self-Join:: Un comportement personnalisé de jointure où une table se combine avec elle-même; Cela est généralement nécessaire pour interroger des tables auto-référencées (ou une entité de relation unaire). Pour la mise en œuvre, voir INNER-JOINs.
Produit cartésien: il combine tous les enregistrements des deux tables sans aucune condition. Techniquement, il renvoie l'ensemble de résultats d'une requête sans WHERE-Clause.
Conformément à la préoccupation et à l'avancement SQL, il existe 3 types de jointures et toutes les jointures RDBMS peuvent être réalisées à l'aide de ces types de jointures.
INNER-JOIN: il fusionne (ou combine) les lignes correspondantes de deux tables. L'appariement est effectué sur la base des colonnes de tables communes et de leur opération de comparaison. Si condition basée sur l'égalité, alors: EQUI-JOIN exécuté, sinon Non-EQUI-Join.
OUTER-JOIN: il fusionne (ou combine) les lignes correspondantes de deux tables et les lignes sans correspondance avec des valeurs NULL. Cependant, une sélection personnalisée de lignes non appariées peut être effectuée, par exemple en sélectionnant une ligne non appariée dans la première table ou la deuxième table par sous-types: LEFT OUTER JOIN et RIGHT OUTER JOIN.
2.1. LEFT Outer JOIN (aka, LEFT-JOIN): Renvoie uniquement les lignes correspondantes de deux tables et sans correspondance avec la table LEFT (c'est-à-dire la première table).
2.2. RIGHT Outer JOIN (aka, RIGHT-JOIN): Renvoie les lignes correspondantes de deux tables et sans correspondance de la table RIGHT uniquement.
2.3. FULL OUTER JOIN (alias OUTER JOIN): renvoie les correspondances et les correspondances des deux tables.
CROSS-JOIN: Cette jointure ne fusionne pas / combine au lieu de cela, elle effectue un produit cartésien.
Remarque: Self-JOIN peut être réalisé par INNER-JOIN, OUTER-JOIN et CROSS-JOIN en fonction des besoins, mais la table doit se joindre à elle-même.
Les étiquettes «Tableau 1» et «Tableau 2» et les étiquettes en dessous sont inappropriées, elles proviennent d'illustrations de intersect/ except/ union; ici les cercles sont les lignes renvoyées par left& rightjoin, comme le disent les étiquettes numérotées. L'image AXB est absurde. cross join= inner join on 1=1& est un cas particulier du premier diagramme.
philipxy
Il convient de mentionner que SQL-92 définit le UNION JOIN. Désormais obsolète dans SQL: 2003.
The Impaler
40
Fait intéressant, la plupart des autres réponses souffrent de ces deux problèmes:
Ils se concentrent uniquement sur les formes de base de jointure
D'abord et avant tout: les JOIN sont des produits cartésiens
C'est pourquoi les diagrammes de Venn les expliquent si inexactement, car un JOIN crée un produit cartésien entre les deux tables jointes. Wikipédia l'illustre bien:
La syntaxe SQL pour les produits cartésiens est CROSS JOIN. Par exemple:
SELECT*-- This just generates all the days in January 2017FROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Here, we're combining all days with all departmentsCROSSJOIN departments
Qui combine toutes les lignes d'une table avec toutes les lignes de l'autre table:
La source:
+--------+ +------------+
| day | | department |
+--------+ +------------+
| Jan 01 | | Dept 1 |
| Jan 02 | | Dept 2 |
| ... | | Dept 3 |
| Jan 30 | +------------+
| Jan 31 |
+--------+
Résultat:
+--------+------------+
| day | department |
+--------+------------+
| Jan 01 | Dept 1 |
| Jan 01 | Dept 2 |
| Jan 01 | Dept 3 |
| Jan 02 | Dept 1 |
| Jan 02 | Dept 2 |
| Jan 02 | Dept 3 |
| ... | ... |
| Jan 31 | Dept 1 |
| Jan 31 | Dept 2 |
| Jan 31 | Dept 3 |
+--------+------------+
Si nous écrivons simplement une liste de tables séparées par des virgules, nous obtiendrons la même chose:
-- CROSS JOINing two tables:SELECT*FROM table1, table2
INNER JOIN (Theta-JOIN)
An INNER JOINest juste un filtre CROSS JOINoù le prédicat de filtre est appelé Thetaen algèbre relationnelle.
Par exemple:
SELECT*-- Same as beforeFROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Now, exclude all days/departments combinations for-- days before the department was createdJOIN departments AS d ON day >= d.created_at
Notez que le mot clé INNERest facultatif (sauf dans MS Access).
Un type spécial de Theta-JOIN est equi JOIN, que nous utilisons le plus. Le prédicat joint la clé primaire d'une table à la clé étrangère d'une autre table. Si nous utilisons la base de données Sakila à titre d'illustration, nous pouvons écrire:
SELECT*FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id
Cela combine tous les acteurs avec leurs films.
Ou aussi, sur certaines bases de données:
SELECT*FROM actor
JOIN film_actor USING(actor_id)JOIN film USING(film_id)
La USING()syntaxe permet de spécifier une colonne qui doit être présente de chaque côté des tables d'une opération JOIN et crée un prédicat d'égalité sur ces deux colonnes.
JOIN NATUREL
D'autres réponses ont répertorié ce "type JOIN" séparément, mais cela n'a pas de sens. C'est juste une forme de sucre syntaxique pour equi JOIN, qui est un cas particulier de Theta-JOIN ou INNER JOIN. NATURAL JOIN collecte simplement toutes les colonnes communes aux deux tables jointes et joint USING()ces colonnes. Ce qui n'est presque jamais utile, en raison de correspondances accidentelles (comme les LAST_UPDATEcolonnes de la base de données Sakila ).
Voici la syntaxe:
SELECT*FROM actor
NATURALJOIN film_actor
NATURALJOIN film
JOINT EXTERIEUR
Maintenant, OUTER JOINest un peu différent INNER JOINcar il crée un UNIONde plusieurs produits cartésiens. Nous pouvons écrire:
-- Convenient syntax:SELECT*FROM a LEFTJOIN b ON<predicate>-- Cumbersome, equivalent syntax:SELECT a.*, b.*FROM a JOIN b ON<predicate>UNIONALLSELECT a.*,NULL,NULL,...,NULLFROM a
WHERENOTEXISTS(SELECT*FROM b WHERE<predicate>)
Personne ne veut écrire ce dernier, donc nous écrivons OUTER JOIN(ce qui est généralement mieux optimisé par les bases de données).
Comme INNER, le mot OUTER- clé est facultatif, ici.
OUTER JOIN se décline en trois saveurs:
LEFT [ OUTER ] JOIN: Le tableau de gauche de l' JOINexpression est ajouté à l'union comme indiqué ci-dessus.
RIGHT [ OUTER ] JOIN: Le tableau de droite de l' JOINexpression est ajouté à l'union comme indiqué ci-dessus.
FULL [ OUTER ] JOIN: Les deux tables de l' JOINexpression sont ajoutées à l'union comme indiqué ci-dessus.
Il existe des syntaxes obsolètes historiques dans Oracle et SQL Server, qui OUTER JOINétaient déjà prises en charge avant que la norme SQL ait une syntaxe pour cela:
-- OracleSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)AND fa.film_id = f.film_id(+)-- SQL ServerSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id
Cela dit, n'utilisez pas cette syntaxe. Je viens de lister cela ici afin que vous puissiez le reconnaître à partir des anciens articles de blog / code hérité.
Partitionné OUTER JOIN
Peu de gens le savent, mais le standard SQL spécifie partitionné OUTER JOIN(et Oracle l'implémente). Vous pouvez écrire des choses comme ceci:
WITH-- Using CONNECT BY to generate all dates in January
days(day)AS(SELECT DATE '2017-01-01'+ LEVEL -1FROM dual
CONNECTBY LEVEL <=31),-- Our departments
departments(department, created_at)AS(SELECT'Dept 1', DATE '2017-01-10'FROM dual UNIONALLSELECT'Dept 2', DATE '2017-01-11'FROM dual UNIONALLSELECT'Dept 3', DATE '2017-01-12'FROM dual UNIONALLSELECT'Dept 4', DATE '2017-04-01'FROM dual UNIONALLSELECT'Dept 5', DATE '2017-04-02'FROM dual
)SELECT*FROM days
LEFTJOIN departments
PARTITIONBY(department)-- This is where the magic happensON day >= created_at
Parties du résultat:
+--------+------------+------------+
| day | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1 | | -- Didn't match, but still get row
| Jan 02 | Dept 1 | | -- Didn't match, but still get row
| ... | Dept 1 | | -- Didn't match, but still get row
| Jan 09 | Dept 1 | | -- Didn't match, but still get row
| Jan 10 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 11 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 12 | Dept 1 | Jan 10 | -- Matches, so get join result
| ... | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 31 | Dept 1 | Jan 10 | -- Matches, so get join result
Le point ici est que toutes les lignes du côté partitionné de la jointure se retrouveront dans le résultat, peu importe si le JOIN correspondent à quelque chose de «l'autre côté de la jointure». Pour faire court: il s'agit de remplir des données éparses dans les rapports. Très utile!
SEMI JOIN
Sérieusement? Aucune autre réponse n'a obtenu cela? Bien sûr que non, car il n'a pas de syntaxe native dans SQL, malheureusement (tout comme ANTI JOIN ci-dessous). Mais nous pouvons utiliser IN()et EXISTS(), par exemple pour trouver tous les acteurs qui ont joué dans des films:
SELECT*FROM actor a
WHEREEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
Le WHERE a.actor_id = fa.actor_idprédicat agit comme le prédicat de semi-jointure. Si vous ne le croyez pas, consultez les plans d'exécution, par exemple dans Oracle. Vous verrez que la base de données exécute une opération SEMI JOIN, pas le EXISTS()prédicat.
SELECT*FROM actor a
WHERENOTEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
Certaines personnes (en particulier les personnes MySQL) écrivent également ANTI JOIN comme ceci:
SELECT*FROM actor a
LEFTJOIN film_actor fa
USING(actor_id)WHERE film_id ISNULL
Je pense que la raison historique est la performance.
JOINT LATÉRAL
OMG, celui-ci est trop cool. Je suis le seul à le mentionner? Voici une requête intéressante:
SELECT a.first_name, a.last_name, f.*FROM actor AS a
LEFTOUTERJOIN LATERAL (SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa USING(film_id)JOIN inventory AS i USING(film_id)JOIN rental AS r USING(inventory_id)JOIN payment AS p USING(rental_id)WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
ON true
Il trouvera le TOP 5 des films générateurs de revenus par acteur. Chaque fois que vous avez besoin d'une requête TOP-N-par-quelque chose, LATERAL JOINsera votre ami. Si vous êtes une personne SQL Server, vous connaissez ce JOINtype sous le nomAPPLY
SELECT a.first_name, a.last_name, f.*FROM actor AS a
OUTERAPPLY(SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa ON f.film_id = fa.film_id
JOIN inventory AS i ON f.film_id = i.film_id
JOIN rental AS r ON i.inventory_id = r.inventory_id
JOIN payment AS p ON r.rental_id = p.rental_id
WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
OK, c'est peut-être de la triche, car une expression LATERAL JOINor APPLYest vraiment une "sous-requête corrélée" qui produit plusieurs lignes. Mais si nous autorisons les "sous-requêtes corrélées", nous pouvons également parler de ...
MULTISET
Ceci n'est vraiment implémenté que par Oracle et Informix (à ma connaissance), mais il peut être émulé dans PostgreSQL en utilisant des tableaux et / ou XML et dans SQL Server en utilisant XML.
MULTISETproduit une sous-requête corrélée et imbrique l'ensemble de lignes résultant dans la requête externe. La requête ci-dessous sélectionne tous les acteurs et pour chaque acteur recueille leurs films dans une collection imbriquée:
SELECT a.*, MULTISET (SELECT f.*FROM film AS f
JOIN film_actor AS fa USING(film_id)WHERE a.actor_id = fa.actor_id
)AS films
FROM actor
Comme vous l' avez vu, il y a plusieurs types de REJOIGNEZ que juste le « ennuyeux » INNER, OUTERet CROSS JOINqui sont généralement mentionnés. Plus de détails dans mon article . Et s'il vous plaît, arrêtez d'utiliser les diagrammes de Venn pour les illustrer.
Equijoin est le cas particulier de la jointure thêta où thêta est égalité. La jointure thêta est analogue à un cas spécial de jointure interne où l'activation est une comparaison thêta d'une colonne de chacune. Quelques décennies après que Codd les a définis, certains manuels ont mal défini la jointure thêta comme une généralisation qui est l'analogue de la jointure interne.
philipxy
@philipxy: Quelque chose de spécifique que je devrais changer dans ma réponse? Vous pourriez suggérer une modification ...
Lukas Eder
10
J'ai créé une illustration qui explique mieux que les mots, à mon avis:
@Niraj Les cercles A & B ne contiennent pas les rangées A & B. Ils sont copiés aveuglément d'ailleurs sans crédit. La jointure croisée est incluse dans le cas de jointure interne, c'est la jointure interne sur 1 = 1. En quoi ces parties de l'image sont-elles "parfaites"?
philipxy
@philipxy Désolé mais cela ne me dérange pas s'il est copié ailleurs. et je ne sais pas ce qui n'est pas correct dans l'image ci-dessus. pour moi c'est ok. La jointure croisée n'est pas décrite ici. Il n'est pas inclus dans une jointure interne ..
Niraj
-3
Je vais pousser ma bête noire: le mot-clé USING.
Si les deux tables des deux côtés de JOIN ont leurs clés étrangères correctement nommées (c'est-à-dire le même nom, pas seulement "id), alors cela peut être utilisé:
Qu'est-ce que c'est
SQL JOIN
?SQL JOIN
est une méthode pour récupérer des données de deux ou plusieurs tables de base de données.Quels sont les différents
SQL JOIN
s?Il y a un total de cinq
JOIN
s. Elles sont :1. REJOINDRE ou REJOINDRE INTERIEUR:
Dans ce type de
JOIN
, nous obtenons tous les enregistrements qui correspondent à la condition dans les deux tables, et les enregistrements dans les deux tables qui ne correspondent pas ne sont pas signalés.En d'autres termes,
INNER JOIN
est basé sur le seul fait que: SEULEMENT les entrées correspondantes dans les DEUX tableaux DEVRAIENT être listées.Notez que
JOIN
sans d' autresJOIN
mots - clés (commeINNER
,OUTER
,LEFT
, etc.) est unINNER JOIN
. En d'autres termes,JOIN
est un sucre syntaxique pourINNER JOIN
(voir: Différence entre JOIN et INNER JOIN ).2. JOINT EXTERIEUR:
OUTER JOIN
récupèreSoit, les lignes correspondantes d'une table et toutes les lignes de l'autre table Ou, toutes les lignes de toutes les tables (peu importe qu'il y ait ou non une correspondance).
Il existe trois types de jointure externe:
2.1 LEFT OUTER JOIN ou LEFT JOIN
Cette jointure renvoie toutes les lignes de la table de gauche conjointement avec les lignes correspondantes de la table de droite. S'il n'y a aucune colonne correspondant dans le tableau de droite, il renvoie des
NULL
valeurs.2.2 JOINT EXTERIEUR DROIT ou JOINT DROIT
Cela
JOIN
renvoie toutes les lignes de la table de droite en conjonction avec les lignes correspondantes de la table de gauche. S'il n'y a aucune colonne correspondant dans le tableau de gauche, il renvoie desNULL
valeurs.2.3 FULL OUTER JOIN ou FULL JOIN
Cela
JOIN
combineLEFT OUTER JOIN
etRIGHT OUTER JOIN
. Il renvoie des lignes de l'une ou l'autre table lorsque les conditions sont remplies et renvoie uneNULL
valeur en l'absence de correspondance.En d'autres termes,
OUTER JOIN
est basé sur le fait que: UNIQUEMENT les entrées correspondantes dans UNE des tables (DROITE ou GAUCHE) ou LES DEUX tables (COMPLÈTE) DEVRAIENT être répertoriées.3. JOINT NATUREL:
Il est basé sur les deux conditions:
JOIN
est sur toutes les colonnes portant le même nom pour l'égalité.Cela semble être de nature plus théorique et en conséquence (probablement) la plupart des SGBD ne prennent même pas la peine de le supporter.
4. CROSS JOIN:
C'est le produit cartésien des deux tables concernées. Le résultat d'une
CROSS JOIN
volonté n'a pas de sens dans la plupart des situations. De plus, nous n'en aurons pas du tout besoin (ou en avons le moins besoin, pour être précis).5. AUTO-JOINDRE:
Il n'est pas une forme différente de
JOIN
, mais plutôt unJOIN
(INNER
,OUTER
, etc.) d'une table à elle - même.JOINs basés sur les opérateurs
Selon l'opérateur utilisé pour une
JOIN
clause, il peut y avoir deux types deJOIN
s. Elles sont1. Equi JOIN:
Pour tout le
JOIN
type (INNER
,OUTER
, etc.), si nous utilisons uniquement l'opérateur d'égalité (=), alors nous disons que l'JOIN
est unEQUI JOIN
.2. Theta JOIN:
C'est la même chose
EQUI JOIN
mais cela permet à tous les autres opérateurs comme>, <,> = etc.la source
Définition:
JOINS est un moyen d'interroger les données qui se sont combinées à partir de plusieurs tables simultanément.
Types de JOINS:
Concernant le SGBDR, il existe 5 types de jointures:
Equi-Join: combine les enregistrements communs de deux tables en fonction de la condition d'égalité. Techniquement, la jointure a été effectuée en utilisant l'opérateur d'égalité (=) pour comparer les valeurs de la clé primaire d'une table et les valeurs de la clé étrangère d'une autre table, donc le jeu de résultats comprend les enregistrements communs (correspondants) des deux tables. Pour la mise en œuvre, voir INNER-JOIN.
Natural-Join: Il s'agit d'une version améliorée d'Equi-Join, dans laquelle l'opération SELECT omet la colonne en double. Pour la mise en œuvre, voir INNER-JOIN
Non-Equi-Join: c'est l'inverse de Equi-join où la condition de jointure utilise des opérateurs différents de l'égalité (=) par exemple,! =, <=,> =,>, <Ou BETWEEN etc. Pour la mise en œuvre, voir INNER-JOIN.
Self-Join:: Un comportement personnalisé de jointure où une table se combine avec elle-même; Cela est généralement nécessaire pour interroger des tables auto-référencées (ou une entité de relation unaire). Pour la mise en œuvre, voir INNER-JOINs.
Produit cartésien: il combine tous les enregistrements des deux tables sans aucune condition. Techniquement, il renvoie l'ensemble de résultats d'une requête sans WHERE-Clause.
Conformément à la préoccupation et à l'avancement SQL, il existe 3 types de jointures et toutes les jointures RDBMS peuvent être réalisées à l'aide de ces types de jointures.
INNER-JOIN: il fusionne (ou combine) les lignes correspondantes de deux tables. L'appariement est effectué sur la base des colonnes de tables communes et de leur opération de comparaison. Si condition basée sur l'égalité, alors: EQUI-JOIN exécuté, sinon Non-EQUI-Join.
OUTER-JOIN: il fusionne (ou combine) les lignes correspondantes de deux tables et les lignes sans correspondance avec des valeurs NULL. Cependant, une sélection personnalisée de lignes non appariées peut être effectuée, par exemple en sélectionnant une ligne non appariée dans la première table ou la deuxième table par sous-types: LEFT OUTER JOIN et RIGHT OUTER JOIN.
2.1. LEFT Outer JOIN (aka, LEFT-JOIN): Renvoie uniquement les lignes correspondantes de deux tables et sans correspondance avec la table LEFT (c'est-à-dire la première table).
2.2. RIGHT Outer JOIN (aka, RIGHT-JOIN): Renvoie les lignes correspondantes de deux tables et sans correspondance de la table RIGHT uniquement.
2.3. FULL OUTER JOIN (alias OUTER JOIN): renvoie les correspondances et les correspondances des deux tables.
CROSS-JOIN: Cette jointure ne fusionne pas / combine au lieu de cela, elle effectue un produit cartésien.
Remarque: Self-JOIN peut être réalisé par INNER-JOIN, OUTER-JOIN et CROSS-JOIN en fonction des besoins, mais la table doit se joindre à elle-même.
Pour plus d'informations:
Exemples:
1.1: INNER-JOIN: implémentation Equi-join
1.2: INNER-JOIN: implémentation de Natural-JOIN
1.3: INNER-JOIN avec implémentation NON-Equi-join
1.4: INNER-JOIN avec SELF-JOIN
2.1: OUTER JOIN (jointure externe complète)
2.2: JOINT GAUCHE
2.3: JOINDRE À DROITE
3.1: CROSS JOIN
3.2: CROSS JOIN-Self JOIN
//OU//
la source
intersect
/except
/union
; ici les cercles sont les lignes renvoyées parleft
&right
join
, comme le disent les étiquettes numérotées. L'image AXB est absurde.cross join
=inner join on 1=1
& est un cas particulier du premier diagramme.UNION JOIN
. Désormais obsolète dans SQL: 2003.Fait intéressant, la plupart des autres réponses souffrent de ces deux problèmes:
J'ai récemment écrit un article sur le sujet: Un guide complet probablement incomplet sur les nombreuses façons de joindre des tables en SQL , que je résumerai ici.
D'abord et avant tout: les JOIN sont des produits cartésiens
C'est pourquoi les diagrammes de Venn les expliquent si inexactement, car un JOIN crée un produit cartésien entre les deux tables jointes. Wikipédia l'illustre bien:
La syntaxe SQL pour les produits cartésiens est
CROSS JOIN
. Par exemple:Qui combine toutes les lignes d'une table avec toutes les lignes de l'autre table:
La source:
Résultat:
Si nous écrivons simplement une liste de tables séparées par des virgules, nous obtiendrons la même chose:
INNER JOIN (Theta-JOIN)
An
INNER JOIN
est juste un filtreCROSS JOIN
où le prédicat de filtre est appeléTheta
en algèbre relationnelle.Par exemple:
Notez que le mot clé
INNER
est facultatif (sauf dans MS Access).( regardez l'article pour des exemples de résultats )
EQUI JOIN
Un type spécial de Theta-JOIN est equi JOIN, que nous utilisons le plus. Le prédicat joint la clé primaire d'une table à la clé étrangère d'une autre table. Si nous utilisons la base de données Sakila à titre d'illustration, nous pouvons écrire:
Cela combine tous les acteurs avec leurs films.
Ou aussi, sur certaines bases de données:
La
USING()
syntaxe permet de spécifier une colonne qui doit être présente de chaque côté des tables d'une opération JOIN et crée un prédicat d'égalité sur ces deux colonnes.JOIN NATUREL
D'autres réponses ont répertorié ce "type JOIN" séparément, mais cela n'a pas de sens. C'est juste une forme de sucre syntaxique pour equi JOIN, qui est un cas particulier de Theta-JOIN ou INNER JOIN. NATURAL JOIN collecte simplement toutes les colonnes communes aux deux tables jointes et joint
USING()
ces colonnes. Ce qui n'est presque jamais utile, en raison de correspondances accidentelles (comme lesLAST_UPDATE
colonnes de la base de données Sakila ).Voici la syntaxe:
JOINT EXTERIEUR
Maintenant,
OUTER JOIN
est un peu différentINNER JOIN
car il crée unUNION
de plusieurs produits cartésiens. Nous pouvons écrire:Personne ne veut écrire ce dernier, donc nous écrivons
OUTER JOIN
(ce qui est généralement mieux optimisé par les bases de données).Comme
INNER
, le motOUTER
- clé est facultatif, ici.OUTER JOIN
se décline en trois saveurs:LEFT [ OUTER ] JOIN
: Le tableau de gauche de l'JOIN
expression est ajouté à l'union comme indiqué ci-dessus.RIGHT [ OUTER ] JOIN
: Le tableau de droite de l'JOIN
expression est ajouté à l'union comme indiqué ci-dessus.FULL [ OUTER ] JOIN
: Les deux tables de l'JOIN
expression sont ajoutées à l'union comme indiqué ci-dessus.Tous ces éléments peuvent être combinés avec le mot clé
USING()
ou avecNATURAL
( j'ai en fait eu un cas d'utilisation dans le monde réelNATURAL FULL JOIN
récemment )Syntaxes alternatives
Il existe des syntaxes obsolètes historiques dans Oracle et SQL Server, qui
OUTER JOIN
étaient déjà prises en charge avant que la norme SQL ait une syntaxe pour cela:Cela dit, n'utilisez pas cette syntaxe. Je viens de lister cela ici afin que vous puissiez le reconnaître à partir des anciens articles de blog / code hérité.
Partitionné
OUTER JOIN
Peu de gens le savent, mais le standard SQL spécifie partitionné
OUTER JOIN
(et Oracle l'implémente). Vous pouvez écrire des choses comme ceci:Parties du résultat:
Le point ici est que toutes les lignes du côté partitionné de la jointure se retrouveront dans le résultat, peu importe si le
JOIN
correspondent à quelque chose de «l'autre côté de la jointure». Pour faire court: il s'agit de remplir des données éparses dans les rapports. Très utile!SEMI JOIN
Sérieusement? Aucune autre réponse n'a obtenu cela? Bien sûr que non, car il n'a pas de syntaxe native dans SQL, malheureusement (tout comme ANTI JOIN ci-dessous). Mais nous pouvons utiliser
IN()
etEXISTS()
, par exemple pour trouver tous les acteurs qui ont joué dans des films:Le
WHERE a.actor_id = fa.actor_id
prédicat agit comme le prédicat de semi-jointure. Si vous ne le croyez pas, consultez les plans d'exécution, par exemple dans Oracle. Vous verrez que la base de données exécute une opération SEMI JOIN, pas leEXISTS()
prédicat.ANTI JOIN
Ceci est juste le contraire de SEMI JOIN ( attention à ne pas utiliser
NOT IN
si , comme il a une mise en garde importante)Voici tous les acteurs sans films:
Certaines personnes (en particulier les personnes MySQL) écrivent également ANTI JOIN comme ceci:
Je pense que la raison historique est la performance.
JOINT LATÉRAL
OMG, celui-ci est trop cool. Je suis le seul à le mentionner? Voici une requête intéressante:
Il trouvera le TOP 5 des films générateurs de revenus par acteur. Chaque fois que vous avez besoin d'une requête TOP-N-par-quelque chose,
LATERAL JOIN
sera votre ami. Si vous êtes une personne SQL Server, vous connaissez ceJOIN
type sous le nomAPPLY
OK, c'est peut-être de la triche, car une expression
LATERAL JOIN
orAPPLY
est vraiment une "sous-requête corrélée" qui produit plusieurs lignes. Mais si nous autorisons les "sous-requêtes corrélées", nous pouvons également parler de ...MULTISET
Ceci n'est vraiment implémenté que par Oracle et Informix (à ma connaissance), mais il peut être émulé dans PostgreSQL en utilisant des tableaux et / ou XML et dans SQL Server en utilisant XML.
MULTISET
produit une sous-requête corrélée et imbrique l'ensemble de lignes résultant dans la requête externe. La requête ci-dessous sélectionne tous les acteurs et pour chaque acteur recueille leurs films dans une collection imbriquée:Comme vous l' avez vu, il y a plusieurs types de REJOIGNEZ que juste le « ennuyeux »
INNER
,OUTER
etCROSS JOIN
qui sont généralement mentionnés. Plus de détails dans mon article . Et s'il vous plaît, arrêtez d'utiliser les diagrammes de Venn pour les illustrer.la source
J'ai créé une illustration qui explique mieux que les mots, à mon avis:
la source
Je vais pousser ma bête noire: le mot-clé USING.
Si les deux tables des deux côtés de JOIN ont leurs clés étrangères correctement nommées (c'est-à-dire le même nom, pas seulement "id), alors cela peut être utilisé:
Je trouve cela très pratique, lisible et pas assez utilisé.
la source