Je suis curieux de savoir pourquoi nous devons utiliser LEFT JOIN
puisque nous pouvons utiliser des virgules pour sélectionner plusieurs tables.
Quelles sont les différences entre LEFT JOIN
et l’utilisation de virgules pour sélectionner plusieurs tables.
Lequel est le plus rapide?
Voici mon code:
SELECT mw.*,
nvs.*
FROM mst_words mw
LEFT JOIN (SELECT no as nonvs,
owner,
owner_no,
vocab_no,
correct
FROM vocab_stats
WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no
WHERE (nvs.correct > 0 )
AND mw.level = 1
...et:
SELECT *
FROM vocab_stats vs,
mst_words mw
WHERE mw.no = vs.vocab_no
AND vs.correct > 0
AND mw.level = 1
AND vs.owner = 1111
Tout d'abord, pour être complètement équivalent, la première requête aurait dû être écrite
SELECT mw.*,
nvs.*
FROM mst_words mw
LEFT JOIN (SELECT *
FROM vocab_stats
WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no
WHERE (nvs.correct > 0 )
AND mw.level = 1
Ainsi, mw. * Et nvs. * Produisent ensemble le même ensemble que le singulier de la deuxième requête *. La requête telle que vous l'avez écrite peut utiliser un INNER JOIN, car elle inclut un filtre sur nvs.correct.
La forme générale
TABLEA LEFT JOIN TABLEB ON <CONDITION>
attempts
pour rechercher des enregistrements TableB en fonction de la condition. En cas d'échec, les résultats de TABLEA sont conservés et toutes les colonnes de TableB sont définies sur NULL. En revanche
TABLEA INNER JOIN TABLEB ON <CONDITION>
également attempts
pour rechercher des enregistrements TableB en fonction de la condition. Cependant, en cas d'échec, l'enregistrement de TableA est supprimé du jeu de résultats en sortie.
La norme ANSI pour CROSS JOIN produit un produit cartésien entre les deux tables.
TABLEA CROSS JOIN TABLEB
-- # or in older syntax, simply using commas
TABLEA, TABLEB
L'intention de la syntaxe est que chaque ligne de TABLEA soit jointe à chaque ligne de TABLEB. Donc 4 lignes sur A et 3 lignes sur B produisent 12 lignes de sortie. Lorsqu'il est associé à des conditions dans la clause WHERE, il se produit parfois le même comportement de INNER JOIN, car elles expriment la même chose (condition entre A et B => keep ou non). Toutefois, la lecture de l'intention est plus claire lorsque vous utilisez INNER JOIN au lieu de virgules.
En termes de performances, la plupart des SGBD traitent une jointure LEFT plus rapidement qu’un INNER JOIN. La notation par virgule peut amener les systèmes de base de données à mal interpréter l’intention et à produire un plan de requête incorrect, un avantage supplémentaire pour la notation SQL92.
Pourquoi avons-nous besoin de LEFT JOIN? Si l'explication de LEFT JOIN ci-dessus n'est toujours pas suffisante (conserver les enregistrements en A sans les correspondances en B), alors considérez que pour obtenir la même chose, vous auriez besoin d'une union complexe entre deux ensembles utilisant l'ancienne notation par virgule même effet. Mais comme indiqué précédemment, cela ne s'applique pas à votre exemple, qui est en réalité un INNER JOIN se cachant derrière un LEFT JOIN.
Remarques:
LEFT OUTER JOIN
.La séparation de JOIN et de WHERE facilite la lecture, car la logique de jointure ne peut être confondue avec les conditions WHERE. Ce sera généralement plus rapide car le serveur n'aura pas besoin de mener deux requêtes distinctes et de combiner les résultats.
Les deux exemples que vous avez donnés ne sont pas vraiment équivalents, car vous avez inclus une sous-requête dans le premier exemple. Ceci est un meilleur exemple:
SELECT vs.*, mw.*
FROM vocab_stats vs, mst_words mw
LEFT JOIN vocab_stats vs ON mw.no = vs.vocab_no
WHERE vs.correct > 0
AND mw.level = 1
AND vs.owner = 1111