Différence entre la jointure naturelle et la jointure interne

197

Quelle est la différence entre une jointure naturelle et une jointure interne?

forgeron
la source
3
Cette question n'est pas un double de l'autre, car il s'agit de jointures INNER vs NATURAL, qui ne sont pas traitées dans l'autre.
1
À un moment donné, cela a été fermé en tant que doublon de Quelle est la différence entre les jointures gauche, droite, externe et interne , mais cette question ne traite pas de la différence entre les jointures internes et les jointures naturelles.
Jonathan Leffler

Réponses:

250

Une différence significative entre INNER JOIN et NATURAL JOIN est le nombre de colonnes renvoyées.

Considérer:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

Le INNER JOINde TableA et TableB sur Colonne1 sera de retour

SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+    
| a.Column1  | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1          |  2        | 1        |   3      |
+------------+-----------+----------+----------+

Le NATURAL JOINde TableA et TableB sur Colonne1 renverra:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

La colonne répétée est évitée.

(AFAICT de la grammaire standard, vous ne pouvez pas spécifier les colonnes de jointure dans une jointure naturelle; la jointure est strictement basée sur le nom. Voir aussi Wikipedia .)

( Il y a un tricheur dans la sortie jointure interne, la a.et les b.parties ne seraient pas dans les noms de colonnes, vous souhaitez simplement avoir column1, column2, column1, column3comme les rubriques. )

Jonathan Leffler
la source
2
J'ai deux tables TableA (Colonne1, Colonne2) et TableB (Colonne2, Colonne3).
2 8
16
La réduction des colonnes dans la sortie est l'aspect le moins important d'une jointure naturelle. Les choses que vous devez savoir sont (A) il se joint automatiquement aux champs du même nom et (B) il va f *** up votre s *** quand vous vous y attendez le moins. Dans mon monde, l'utilisation d'une jointure naturelle est un motif de licenciement.
8
@JonofAllTrades Pouvez-vous expliquer plus en détail ce qui NATURAL JOINva ruiner exactement , pourquoi c'est inattendu et dans quel monde vous vous trouvez?
Bryson
35
Ceci est quelque peu résolu dans la réponse de user166390. Supposons que vous ayez une jointure naturelle entre Customerset Employees, rejoignant EmployeeID. Employeesa également un ManagerIDchamp. Tout va bien. Puis, un jour, quelqu'un ajoute un ManagerIDchamp à la Customerstable. Votre jointure ne sera pas interrompue (ce serait une grâce), mais elle inclura désormais un deuxième champ et fonctionnera de manière incorrecte . Ainsi, un changement apparemment inoffensif peut briser quelque chose de très éloigné. TRÈS MAUVAIS. Le seul avantage d'une jointure naturelle est d'économiser un peu de frappe et l'inconvénient est substantiel.
2
@Jonathan, Concernant votre réponse, vous avez déclaré que cela SELECT * FROM TableA INNER JOIN TableB USING (Column1)donne 4 colonnes. Ce n'est pas correct car SELECT * FROM TableA INNER JOIN TableB USING (Column1)et SELECT * FROM TableA NATURAL JOIN TableBsont égaux, ils donnent tous les deux 3 colonnes.
Pacerier
81
  • Une jointure interne est celle où la ligne correspondante dans la table jointe est requise pour qu'une ligne de la première table soit renvoyée
  • Une jointure externe est une jointure dans laquelle la ligne correspondante dans la table jointe n'est pas requise pour qu'une ligne de la première table soit renvoyée
  • Une jointure naturelle est une jointure (vous pouvez avoir l'un natural leftou l' autre natural right) qui suppose que les critères de jointure correspondent aux colonnes du même nom dans les deux tables.

J'éviterais d'utiliser des jointures naturelles comme la peste, car les jointures naturelles sont:

  • pas standard SQL [SQL 92] et donc pas portable, pas particulièrement lisible (par la plupart des codeurs SQL) et éventuellement non pris en charge par divers outils / bibliothèques
  • non informatif; vous ne pouvez pas dire sur quelles colonnes sont jointes sans faire référence au schéma
  • vos conditions de jointure sont invisiblement vulnérables aux modifications de schéma - s'il existe plusieurs colonnes de jointure naturelles et qu'une de ces colonnes est supprimée d'une table, la requête s'exécutera toujours, mais probablement pas correctement et ce changement de comportement sera silencieux
  • ne vaut guère l'effort; vous économisez seulement environ 10 secondes de frappe
Bohème
la source
2
Je pense que gauche / droite pour l'extérieur devrait être mentionné (puisque l'extérieur est mentionné du tout). Mais sinon, agréable et concis: il ne manque que les jolis exemples de diagrammes d'enregistrement SQL.
2
NATURAL LEFT et NATURAL RIGHT existent également. Mais oui, évitez-les toujours.
MatBailie
1
@Bohemian, En ce qui concerne "les éviter comme la peste", il existe de vrais cas d'utilisation pour les jointures naturelles où ils sont utiles. mariadb.com/kb/en/sql-99/natural-join "... Les" Livres NATURAL JOIN Checkouts"à l'
Pacerier
2
@sqlvovel il y a beaucoup de mal avec votre commentaire, en particulier il est incorrect. Les colonnes de jointure ne peuvent pas être "spécifiées dans une liste de sélection". La définition d'une jointure naturelle est de joindre * toutes les colonnes portant le même nom *. D'après le document MySQL: Le NATURAL [LEFT] JOIN de deux tables est défini pour être sémantiquement équivalent à un INNER JOIN ou un LEFT JOIN avec une clause USING qui nomme toutes les colonnes qui existent dans les deux tables. . Et une autre chose - en pratique, c'est inutile, car il idest omniprésent et inutile de se joindre à; les noms de clé étrangère habituels sont tablename_id. Les jointures naturelles sont une mauvaise, mauvaise, mauvaise idée.
Bohème
2
Il n'y a pas de double colonne retournée dans ma requête. L'un des avantages de la sémantique NJ est que les colonnes dupliquées ne sont jamais renvoyées. Votre requête précédente était également "moins sûre" que la mienne car elle échouerait si une colonne appelée "a" était ajoutée à t2 (car la condition de jointure sans alias est ambiguë). Je soupçonne que vos préjugés contre NJ sont basés sur le fait que vous ne l'avez pas essayé dans un produit où SQL standard est correctement pris en charge. La question ici concerne SQL, pas MySQL - des choses très différentes. Vous n'avez toujours pas corrigé votre réponse concernant le fait qu'elle n'est pas standard.
nvogel
27

Une jointure naturelle n'est qu'un raccourci pour éviter de taper, avec la présomption que la jointure est simple et correspond aux champs du même nom.

SELECT
  *
FROM
  table1
NATURAL JOIN
  table2
    -- implicitly uses `room_number` to join

Est le même que...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON table1.room_number = table2.room_number

Ce que vous ne pouvez pas faire avec le format de raccourci, cependant, c'est des jointures plus complexes ...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON (table1.room_number = table2.room_number)
    OR (table1.room_number IS NULL AND table2.room_number IS NULL)
MatBailie
la source
2
@JonathanLeffler - Dans MySQL, certainement.
MatBailie
3
OK - intéressant. J'ai demandé parce que le standard SQL ne semble pas le permettre (mais les extensions sont toujours possibles).
Jonathan Leffler
SGBD qui permet cette syntaxe non standard: NATURAL JOIN ... USING ()? La norme est soit a NATURAL JOIN boua JOIN b USING (c)
ypercubeᵀᴹ
1
"juste un raccourci pour éviter de taper" est une inexactitude. Sa caractéristique la plus importante est qu'elle n'entraîne pas de colonnes en double.
jour,
... par exemple, le résultat de votre requête qui utilise la jointure naturelle aura une seule colonne nommée room_number, tandis que vos jointures internes auront deux colonnes nommées room_number.
jour,
13

SQL n'est pas fidèle au modèle relationnel à bien des égards. Le résultat d'une requête SQL n'est pas une relation car elle peut avoir des colonnes avec des noms en double, des colonnes `` anonymes '' (sans nom), des lignes en double, des valeurs nulles, etc. SQL ne traite pas les tables comme des relations car elle repose sur l'ordre des colonnes, etc.

L'idée NATURAL JOINsous-jacente à SQL est de faciliter la fidélité au modèle relationnel. Le résultat de l'une NATURAL JOINdes deux tables aura des colonnes dédoublonnées par nom, donc pas de colonnes anonymes. De même, UNION CORRESPONDINGet EXCEPT CORRESPONDINGsont fournis pour répondre à la dépendance de SQL sur l'ordre des colonnes dans la UNIONsyntaxe existante .

Cependant, comme pour toutes les techniques de programmation, la discipline doit être utile. Une condition pour réussir NATURAL JOINest des colonnes nommées de manière cohérente, car les jointures sont implicites sur des colonnes avec les mêmes noms (il est dommage que la syntaxe pour renommer les colonnes en SQL soit verbeuse mais l'effet secondaire est d'encourager la discipline lors du nommage des colonnes dans les tables de base et VIEWs :)

Notez qu'un SQL NATURAL JOINest une équi-jointure **, mais ce n'est pas un obstacle à l'utilité. Considérez que si NATURAL JOINle seul type de jointure était pris en charge dans SQL, il serait toujours relationnellement complet .

S'il est en effet vrai que tout NATURAL JOINpeut être écrit à l'aide de INNER JOINet projection ( SELECT), il est également vrai que tout INNER JOINpeut être écrit à l'aide de product ( CROSS JOIN) et restriction ( WHERE); notez en outre qu'un NATURAL JOINentre tableaux sans nom de colonne en commun donnera le même résultat que CROSS JOIN. Donc, si vous êtes uniquement intéressé par les résultats qui sont des relations (et pourquoi jamais?!), NATURAL JOINC'est le seul type de jointure dont vous avez besoin. Bien sûr, il est vrai que dans une perspective de conception de langage, les raccourcis tels que INNER JOINet CROSS JOINont leur valeur, mais considèrent également que presque toutes les requêtes SQL peuvent être écrites de 10 manières syntaxiquement différentes, mais sémantiquement équivalentes, et c'est ce qui rend les optimiseurs SQL si durs développer.

Voici quelques exemples de requêtes (utilisant la base de données de pièces et fournisseurs habituelles ) qui sont sémantiquement équivalentes:

SELECT *
  FROM S NATURAL JOIN SP;

-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
  FROM S INNER JOIN SP 
          USING (SNO);                        

-- Alternative projection
SELECT S.*, PNO, QTY
  FROM S INNER JOIN SP 
          ON S.SNO = SP.SNO;

-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
  FROM S INNER JOIN SP 
      ON S.SNO = SP.SNO;

-- 'Old school'
SELECT S.*, PNO, QTY
  FROM S, SP 
 WHERE S.SNO = SP.SNO;

** La jointure relationnelle naturelle n'est pas une équijoin, c'est une projection d'une. - philipxy

un jour
la source
La jointure relationnelle naturelle n'est pas une équijoin, c'est une projection d'une. La jointure naturelle SQL est une équijoin SQL (doublons possibles) - elle est définie en termes de jointure interne utilisant.
philipxy
@philipxy: Merci, j'ai apporté des modifications. N'hésitez pas à modifier - ceci ou l'une de mes réponses - pour les inexactitudes et les malentendus.
J'apprends
9

Une NATURALjointure est juste une syntaxe courte pour une jointure spécifique INNER - ou "équi-jointure" - et, une fois la syntaxe déployée, les deux représentent la même opération d'algèbre relationnelle. Ce n'est pas un "type différent" de jointure, comme dans le cas de OUTER( LEFT/ RIGHT) ou de CROSSjointures.

Voir la section equi-join sur Wikipedia:

Une jointure naturelle offre une spécialisation supplémentaire des équi-jointures. Le prédicat de jointure survient implicitement en comparant toutes les colonnes des deux tables qui ont les mêmes noms de colonne dans les tables jointes. La table jointe résultante contient une seule colonne pour chaque paire de colonnes portant le même nom.

La plupart des experts conviennent que les JOINTS NATURELS sont dangereux et déconseillent donc fortement leur utilisation. Le danger vient de l'ajout par inadvertance d'une nouvelle colonne, nommée de la même manière qu'une autre colonne ...

Autrement dit, toutes les NATURALjointures peuvent être écrites sous forme de INNERjointures (mais l'inverse n'est pas vrai). Pour ce faire, il suffit de créer le prédicat explicitement - par exemple USINGou ON- et, comme l'a souligné Jonathan Leffler, sélectionnez les colonnes de l'ensemble de résultats souhaitées pour éviter les "doublons" si vous le souhaitez.

Codage heureux.


(Le NATURALmot-clé peut également être appliqué à LEFTet RIGHTjointures, et la même chose s'applique. Une NATURAL LEFT/RIGHTjointure n'est qu'une courte syntaxe pour une jointure spécifique LEFT/RIGHT .)

Communauté
la source
2
"NATURAL join est juste une syntaxe courte pour [snip]" equi-join "- et, une fois la syntaxe déballée, les deux représentent la même algèbre relationnelle" - vous avez raison: c'est le cas de l'algèbre relationnelle mais votre réponse échoue après cela, par exemple "La plupart des experts conviennent que les JOINTS NATURELS sont dangereux et découragent donc fortement leur utilisation" - quels experts de l'algèbre relationnelle disent cela?!
onedaywhen
2

Jointure naturelle: c'est la combinaison ou le résultat combiné de toutes les colonnes des deux tables. Il renverra toutes les lignes de la première table par rapport à la deuxième table.

Jointure interne: cette jointure fonctionnera sauf si l'un des noms de colonne doit être sxame dans deux tables

Victor Bhatti
la source
3
Je ne pense pas que votre réponse soit suffisamment claire et il faudrait une grande réécriture pour la corriger.
jour,
0

Une jointure naturelle est l'endroit où 2 tables sont jointes sur la base de toutes les colonnes communes.

colonne commune: est une colonne qui a le même nom dans les deux tables + a des types de données compatibles dans les deux tables. Vous ne pouvez utiliser que l'opérateur =

Une jointure interne est l'endroit où 2 tables sont jointes sur la base des colonnes communes mentionnées dans la clause ON.

colonne commune: est une colonne qui a des types de données compatibles dans les deux tables mais qui n'a pas besoin d'avoir le même nom. Vous ne pouvez utiliser que tout opérateur comme comparision =, <=, >=, <, >,<>

Suchitra Phadke
la source
-2

la différence est que dans la jointure interne (equi / default) et la jointure naturelle qui, dans la victoire de la colonne commune natuarl join, seront affichées en une seule fois, mais la jointure interne / equi / default / simple la colonne commune sera affichée en double.

Rajat Gupta
la source
-2

La jointure interne et la jointure naturelle sont presque identiques, mais il existe une légère différence entre elles. La différence est dans la jointure naturelle, pas besoin de spécifier de condition mais dans la condition de jointure interne est obligatoire. Si nous spécifions la condition dans la jointure interne, les tables résultantes sont comme un produit cartésien.

rashedcs
la source
Pourquoi n'est-il pas nécessaire de spécifier des conditions de jointure? Dans quelles circonstances la spécification de conditions dans une jointure interne aboutirait-elle à quelque chose comme un produit cartésien?
jour,
Appeler la jonction extérieure et intérieure "presque la même chose" est un léger euphémisme. Peut-être pourriez-vous développer votre évaluation?
TMOTTM
-3
mysql> SELECT  * FROM tb1 ;
+----+------+
| id | num  |
+----+------+
|  6 |   60 |
|  7 |   70 |
|  8 |   80 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

mysql> SELECT  * FROM tb2 ;
+----+------+
| id | num  |
+----+------+
|  4 |   40 |
|  5 |   50 |
|  9 |   90 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

JOINTURE INTERNE :

mysql> SELECT  * FROM tb1 JOIN tb2 ; 
+----+------+----+------+
| id | num  | id | num  |
+----+------+----+------+
|  6 |   60 |  4 |   40 |
|  7 |   70 |  4 |   40 |
|  8 |   80 |  4 |   40 |
|  1 |    1 |  4 |   40 |
|  2 |    2 |  4 |   40 |
|  3 |    3 |  4 |   40 |
|  6 |   60 |  5 |   50 |
|  7 |   70 |  5 |   50 |
|  8 |   80 |  5 |   50 |
.......more......
return 36 rows in set (0.01 sec) 
AND NATURAL JOIN :

    mysql> SELECT  * FROM tb1 NATURAL JOIN tb2 ;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |    1 |
    |  2 |    2 |
    |  3 |    3 |
    +----+------+
    3 rows in set (0.01 sec)
zloctb
la source
-4

Jointure interne, joignez deux tables dont le nom de colonne est identique.

Jointure naturelle, joignez deux tables où le nom de la colonne et les types de données sont identiques.

Tejeshwar
la source
C'est complètement incorrect. A NATURAL JOIN(comme plusieurs personnes l'ont souligné il y a des années) est celui où les noms de colonne sont les mêmes. Le type de données n'a pas besoin d'être le même. Les champs utilisés pour un INNER JOINbesoin n'ont pas le même nom.