L'ancienne syntaxe, avec juste la liste des tables et l'utilisation de la WHERE
clause pour spécifier les critères de jointure, est obsolète dans la plupart des bases de données modernes.
Ce n'est pas seulement pour le show, l'ancienne syntaxe a la possibilité d'être ambiguë lorsque vous utilisez les jointures INNER et OUTER dans la même requête.
Laisse moi te donner un exemple.
Supposons que vous ayez 3 tables dans votre système:
Company
Department
Employee
Chaque table contient de nombreuses lignes, liées entre elles. Vous avez plusieurs entreprises, et chaque entreprise peut avoir plusieurs départements, et chaque département peut avoir plusieurs employés.
Ok, alors maintenant vous voulez faire ce qui suit:
Répertoriez toutes les entreprises et incluez tous leurs services et tous leurs employés. Notez que certaines entreprises n'ont pas encore de service, mais assurez-vous de les inclure également. Assurez-vous de ne récupérer que les départements qui ont des employés, mais répertoriez toujours toutes les entreprises.
Vous faites donc ceci:
SELECT * -- for simplicity
FROM Company, Department, Employee
WHERE Company.ID *= Department.CompanyID
AND Department.ID = Employee.DepartmentID
Notez que le dernier il y a une jointure interne, afin de remplir les critères que vous ne voulez que des départements avec des personnes.
Ok, alors qu'est-ce qui se passe maintenant. Eh bien, le problème est que cela dépend du moteur de base de données, de l'optimiseur de requêtes, des index et des statistiques de table. Laisse-moi expliquer.
Si l'optimiseur de requêtes détermine que la façon de procéder consiste à prendre d'abord une entreprise, puis à trouver les services, puis à effectuer une jointure interne avec les employés, vous n'obtiendrez aucune entreprise qui n'a pas de service.
La raison en est que la WHERE
clause détermine quelles lignes se retrouvent dans le résultat final, et non des parties individuelles des lignes.
Et dans ce cas, en raison de la jointure gauche, la colonne Department.ID sera NULL, et donc en ce qui concerne la jointure interne à l'employé, il n'y a aucun moyen de respecter cette contrainte pour la ligne Employé, et donc ce ne sera pas le cas. apparaître.
En revanche, si l'optimiseur de requêtes décide d'aborder la jointure département-employé, puis de faire une jointure gauche avec les entreprises, vous les verrez.
L'ancienne syntaxe est donc ambiguë. Il n'y a aucun moyen de spécifier ce que vous voulez, sans traiter des indices de requête, et certaines bases de données n'ont aucun moyen.
Entrez la nouvelle syntaxe, avec celle que vous pouvez choisir.
Par exemple, si vous voulez toutes les entreprises, comme l'indique la description du problème, voici ce que vous écririez:
SELECT *
FROM Company
LEFT JOIN (
Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
) ON Company.ID = Department.CompanyID
Ici, vous spécifiez que vous souhaitez que la jointure département-employé se fasse en une seule jointure, puis vous laissez les résultats de cette jointure avec les entreprises.
De plus, supposons que vous ne souhaitiez que les départements contenant la lettre X dans leur nom. Encore une fois, avec les jointures à l'ancienne, vous risquez également de perdre la société, si elle n'a pas de départements avec un X dans son nom, mais avec la nouvelle syntaxe, vous pouvez le faire:
SELECT *
FROM Company
LEFT JOIN (
Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
) ON Company.ID = Department.CompanyID AND Department.Name LIKE '%X%'
Cette clause supplémentaire est utilisée pour la jointure, mais n'est pas un filtre pour la ligne entière. Ainsi, la ligne peut apparaître avec des informations sur la société, mais peut avoir des valeurs NULL dans toutes les colonnes département et employé pour cette ligne, car il n'y a pas de département avec un X dans son nom pour cette société. C'est difficile avec l'ancienne syntaxe.
C'est pourquoi, entre autres fournisseurs, Microsoft a déconseillé l'ancienne syntaxe de jointure externe, mais pas l'ancienne syntaxe de jointure interne, depuis SQL Server 2005 et versions ultérieures. La seule façon de parler à une base de données exécutée sur Microsoft SQL Server 2005 ou 2008, en utilisant l'ancienne syntaxe de jointure externe, est de définir cette base de données en mode de compatibilité 8.0 (alias SQL Server 2000).
De plus, l'ancienne méthode, en lançant un tas de tables sur l'optimiseur de requête, avec un tas de clauses WHERE, revenait à dire "vous voici, faites de votre mieux". Avec la nouvelle syntaxe, l'optimiseur de requêtes a moins de travail à faire pour comprendre quelles parties vont ensemble.
Alors voilà.
LEFT and INNER JOIN est la vague du futur.