web-dev-qa-db-fra.com

Quand utiliser LEFT JOIN et quand utiliser INNER JOIN?

J'ai l'impression qu'on m'a toujours appris à utiliser LEFT JOINs et que je les vois souvent mélangés à INNERs pour accomplir le même type de requête dans plusieurs morceaux de code censés faire la même chose sur différentes pages. Voici:

SELECT ac.reac, pt.pt_name, soc.soc_name, pt.pt_soc_code
FROM
  AECounts ac
  INNER JOIN 1_low_level_term llt on ac.reac = llt.llt_name
  LEFT JOIN 1_pref_term pt ON llt.pt_code = pt.pt_code
  LEFT JOIN 1_soc_term soc ON pt.pt_soc_code = soc.soc_code
LIMIT 100,10000

C’est celui sur lequel je travaille:

Je vois beaucoup comme:

SELECT COUNT(DISTINCT p.`case`) as count
FROM FDA_CaseReports cr
  INNER JOIN ae_indi i ON i.isr = cr.isr
  LEFT JOIN ae_case_profile p ON cr.isr = p.isr

On dirait que le LEFT peut aussi bien être INNER. Y at-il un piège?

28
cerd

Y a-t-il un piège? Oui, les jointures à gauche sont une forme de jointure externe, alors que les jointures internes sont une forme de jointure interne.

Voici des exemples qui montrent la différence. Nous allons commencer avec les données de base:

mysql> select * from j1;
+----+------------+
| id | thing      |
+----+------------+
|  1 | hi         |
|  2 | hello      |
|  3 | guten tag  |
|  4 | ciao       |
|  5 | buongiorno |
+----+------------+

mysql> select * from j2;
+----+-----------+
| id | thing     |
+----+-----------+
|  1 | bye       |
|  3 | tschau    |
|  4 | au revoir |
|  6 | so long   |
|  7 | tschuessi |
+----+-----------+

Et nous verrons ici la différence entre une jointure interne et une jointure gauche:

mysql> select * from j1 inner join j2 on j1.id = j2.id;
+----+-----------+----+-----------+
| id | thing     | id | thing     |
+----+-----------+----+-----------+
|  1 | hi        |  1 | bye       |
|  3 | guten tag |  3 | tschau    |
|  4 | ciao      |  4 | au revoir |
+----+-----------+----+-----------+

Hmm, 3 rangées.

mysql> select * from j1 left join j2 on j1.id = j2.id;
+----+------------+------+-----------+
| id | thing      | id   | thing     |
+----+------------+------+-----------+
|  1 | hi         |    1 | bye       |
|  2 | hello      | NULL | NULL      |
|  3 | guten tag  |    3 | tschau    |
|  4 | ciao       |    4 | au revoir |
|  5 | buongiorno | NULL | NULL      |
+----+------------+------+-----------+

Wow, 5 rangées! Qu'est-il arrivé?

Les jointures externes telles que left join préservent les lignes qui ne correspondent pas. Ainsi, les lignes avec les identificateurs 2 et 5 sont préservées par la requête de jointure gauche. Les colonnes restantes sont remplies avec NULL.

En d'autres termes, les jointures gauche et interne ne sont pas interchangeables.

90
Matt Fenwick

Voici une réponse approximative, c'est en quelque sorte ma façon de penser les jointures. En espérant que cela sera plus utile qu'une réponse très précise en raison des problèmes de mathématiques susmentionnés ... ;-)

Les jointures internes réduisent l'ensemble des retours de lignes. Les jointures externes (gauche ou droite) ne changent pas le nombre de lignes renvoyées, mais "ramassent" des colonnes supplémentaires si possible.

Dans votre premier exemple, le résultat sera des lignes de AECounts qui correspondent aux conditions spécifiées dans la table 1_low_level_term. Ensuite, pour ces lignes, il essaie de joindre 1_pref_term et 1_soc_term. Mais s'il n'y a pas de correspondance, les lignes restent et les colonnes jointes sont nulles. 

11
rob

Une jointure interne renverra uniquement les lignes contenant des valeurs correspondantes dans les deux tables, tandis qu'une jointure gauche renverra toutes les lignes de la table gauche, même s'il n'y a pas de ligne correspondante dans la table droite

Un exemple rapide

TableA
ID   Value
1    TableA.Value1
2    TableA.Value2
3    TableA.Value3

TableB
ID   Value
2    TableB.ValueB
3    TableB.ValueC

Un INNER JOIN produit:

SELECT a.ID,a.Value,b.ID,b.Value 
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID

a.ID    a.Value            b.ID    b.Value
2       TableA.Value2      2       TableB.ValueB
3       TableA.Value3      3       TableB.ValueC

Un LEFT JOIN produit:

SELECT a.ID,a.Value,b.ID,b.Value 
FROM TableA a LEFT JOIN TableB b ON b.ID = a.ID

a.ID    a.Value            b.ID    b.Value
1       TableA.Value1      NULL    NULL
2       TableA.Value2      2       TableB.ValueB
3       TableA.Value3      3       TableB.ValueC

Comme vous pouvez le constater, LEFT JOIN inclut la ligne de TableA où ID = 1 même s'il n'y a pas de ligne correspondante dans TableB où ID = 1, alors que INNER JOIN exclut la ligne spécifiquement car il n'y a pas de ligne correspondante dans TableB

HTH

5
philf2b

Utilisez une jointure interne lorsque vous souhaitez que seuls les résultats apparaissant dans les deux tables correspondent à la condition de jointure.

Utilisez une jointure gauche lorsque vous souhaitez obtenir tous les résultats de la table A, mais si la table B contient des données pertinentes pour certains enregistrements de la table A, vous souhaitez également utiliser ces données dans la même requête.

Utilisez une jointure complète lorsque vous souhaitez obtenir tous les résultats des deux tables.

1
Seung Bae Im

Pour les débutants, parce que cela m’a aidé quand j’en étais un: INNER JOIN est toujours un sous-ensemble de LEFT ou de RIGHT JOIN et tous ces éléments sont toujours des sous-ensembles de FULL JOIN. Cela m'a aidé à comprendre l'idée de base.

0
Scott