Retour à la liste des articles Articles
8 minutes de lecture

Quelle est la différence entre WHERE et ON dans les jointures SQL ?

Lorsque vous joignez des tables en SQL, vous pouvez avoir des conditions dans une clause ON et dans une clause WHERE. La différence entre les deux est souvent source de confusion. Dans cet article, nous aborderons ce sujet en vous rappelant d'abord l'objectif des clauses ON et WHERE, puis en vous montrant à l'aide d'exemples quels types de conditions doivent figurer dans chacune de ces clauses.

La clause ON et la clause WHERE peuvent toutes deux spécifier des conditions. Mais y a-t-il des différences entre elles ? Si oui, où devez-vous spécifier quelles conditions dans votre requête SQL ? Nous allons le découvrir ensemble !

Conditions ON et WHERE

L'objectif de la clause ON est de spécifier les conditions de jointure, c'est-à-dire de définir comment les tables doivent être jointes. Plus précisément, vous définissez comment les enregistrements doivent être mis en correspondance.

En revanche, l'objectif de la clauseWHERE est de spécifier les conditions de filtrage, c'est-à-dire de définir les lignes qui doivent être conservées dans le jeu de résultats.

Prenons un exemple pour comprendre la différence. Nous avons les deux tables suivantes qui (1) répertorient les utilisateurs (la table users) de notre site Web de location et (2) les maisons (la table houses) disponibles à la location.

users
idnameregistration_date
11Jane Stewart2020-11-30
12Mary Cooper2015-06-12
13John Watson2015-01-31
14Christian Wood2018-03-03
15William Grey2021-05-12
16Brandon Evans2018-05-08
17Isabella Gonsalez2020-12-12
18Diana Taylor2020-06-30
19Luke Wilson2019-11-17
20Michael Lee2020-02-15

houses
idaddresscityowner_idbedrooms
101Brook Street, 5Cardiff124
102Richmond Street, 1Cardiff121
103Cromwell Road, 23Liverpool132
104Hastings Road, 109York152
105Bedford Road, 2Bristol161
106Queen Street, 45Bristol163
107Mayfield Road, 34Cardiff123
SELECT u.id, u.name, u.registration_date, h.address, h.city
FROM users u
JOIN houses h
ON u.id = h.owner_id
WHERE u.registration_date < '2020-01-01';

Notez que nous avons des conditions à la fois dans la clause ON et dans la clause WHERE:

  • Avec la condition ON, nous spécifions que les tables doivent être jointes en faisant correspondre la colonne id dans la table des utilisateurs et la colonne owner_id dans les maisons.
  • Avec la condition WHERE, nous filtrons le jeu de résultats en ne gardant que les utilisateurs qui se sont inscrits avant le 1er janvier 2020.

Ainsi, nous avons utilisé les conditions ON et WHERE en fonction de leur objectif, ce qui donne une requête SQL claire et lisible.

Voici l'ensemble des résultats :

idnameregistration_dateaddresscity
12Mary Cooper2015-06-12Brook Street, 5Cardiff
12Mary Cooper2015-06-12Richmond Street, 1Cardiff
13John Watson2015-01-31Cromwell Road, 23Liverpool
16Brandon Evans2018-05-08Bedford Road, 2Bristol
16Brandon Evans2018-05-08Queen Street, 45Bristol
12Mary Cooper2015-06-12Mayfield Road, 34Cardiff

Vous n'êtes pas sûr du fonctionnement de JOIN dans notre requête SQL ? Entraînez-vous à joindre des tables avec ce cours interactif sur les jointures SQL.

Conditions ON et WHERE dans les INNER JOINs

Dans l'exemple ci-dessus, nous pouvons voir comment les conditions ON et WHERE sont utilisées en fonction de leur objectif respectif et de la pratique courante.

Toutefois, il est utile de savoir que, pour (INNER) JOINs, vous pouvez spécifier à la fois la condition JOIN et la condition de filtrage avec une clause ON. Par exemple, nous pouvons obtenir le même résultat que ci-dessus avec la requête SQL suivante :

SELECT u.id, u.name, u.registration_date, h.address, h.city
FROM users u
JOIN houses h
ON u.id = h.owner_id AND u.registration_date < '2020-01-01';

Cette requête est exécutée de la même manière. Cela dit, je ne recommande pas de mélanger la condition de jointure et la condition de filtrage dans la même clause. Si vous comparez les deux requêtes, vous voyez que la première est plus lisible :

  • Il est plus facile de suivre la première requête : d'abord, vous joignez les tables par une certaine condition, puis vous filtrez le résultat par une autre condition.
  • L'intention de l'ensemble de la requête est plus claire pour le lecteur extérieur lorsque les conditions sont séparées en suivant les règles.

Conditions ON et WHERE dans les jointures OUTER

Lorsqu'il s'agit de OUTER JOINs (c'est-à-dire LEFT JOIN, RIGHT JOIN et FULL JOIN), il est essentiel d'utiliser les conditions ON et WHERE comme il se doit. Sinon, vous obtiendrez des résultats erronés. Prenons un exemple.

Une fois encore, nous voulons obtenir la liste des utilisateurs qui se sont inscrits avant le 1er janvier 2020, ainsi que leurs maisons respectives. Cette fois, cependant, nous voulons conserver tous les utilisateurs, y compris ceux qui n'ont pas de maison enregistrée sur notre site de location. Ainsi, nous allons faire un LEFT JOIN au lieu d'un JOIN (c'est-à-dire un INNER JOIN).

Nous allons voir s'il y a des différences entre le fait de spécifier la condition de filtrage dans la clause ON et de la spécifier dans la clause WHERE. Si nous suivons les règles et utilisons les conditions comme prévu, nous obtenons la requête suivante :

SELECT u.id, u.name, u.registration_date, h.address, h.city
FROM users u
LEFT JOIN houses h
ON u.id = h.owner_id
WHERE u.registration_date < '2020-01-01';
idnameregistration_dateaddresscity
12Mary Cooper2015-06-12Brook Street, 5Cardiff
12Mary Cooper2015-06-12Richmond Street, 1Cardiff
13John Watson2015-01-31Cromwell Road, 23Liverpool
16Brandon Evans2018-05-08Bedford Road, 2Bristol
16Brandon Evans2018-05-08Queen Street, 45Bristol
12Mary Cooper2015-06-12Mayfield Road, 34Cardiff
19Luke Wilson2019-11-17NULLNULL
14Christian Wood2018-03-03NULLNULL

Le résultat est bon. Nous avons obtenu tous les utilisateurs que nous avons obtenus dans notre exemple initial. En outre, nous avons deux autres utilisateurs qui n'ont pas de maison correspondante sur notre site Web, mais qui ont été inclus dans l'ensemble de résultats en raison de la clause LEFT JOIN. Notez que tous deux se sont inscrits avant le 1er janvier 2020, comme spécifié dans notre condition de filtrage.

Obtenons-nous le même résultat si nous mélangeons la condition de jointure et la condition de filtrage dans la clause ON? C'est ce que nous allons voir :

SELECT u.id, u.name, u.registration_date, h.address, h.city
FROM users u
LEFT JOIN houses h
ON u.id = h.owner_id AND u.registration_date < '2020-01-01';
idnameregistration_dateaddresscity
11Jane Stewart2020-11-30NULLNULL
12Mary Cooper2015-06-12Mayfield Road, 34Cardiff
12Mary Cooper2015-06-12Richmond Street, 1Cardiff
12Mary Cooper2015-06-12Brook Street, 5Cardiff
13John Watson2015-01-31Cromwell Road, 23Liverpool
14Christian Wood2018-03-03NULLNULL
15William Grey2021-05-12NULLNULL
16Brandon Evans2018-05-08Queen Street, 45Bristol
16Brandon Evans2018-05-08Bedford Road, 2Bristol
17Isabella Gonsalez2020-12-12NULLNULL
18Diana Taylor2020-06-30NULLNULL
19Luke Wilson2019-11-17NULLNULL
20Michael Lee2020-02-15NULLNULL

Comme vous pouvez le voir, les résultats sont différents. Tous les utilisateurs sont inclus, même ceux qui se sont inscrits en 2020 ou 2021. Cela s'explique par le fait que LEFT JOIN conserve tous les enregistrements de la table de gauche, même lorsque la logique de ON échoue. Donc, dans cet exemple, spécifier la condition de filtrage dans la clause ON ne fonctionne pas pour nous. Pour obtenir le bon résultat, nous devons spécifier les conditions comme prévu.

Il est intéressant de noter qu'il existe des situations dans lesquelles la condition WHERE peut "annuler" l'intention d'une clause OUTER JOIN. Par exemple, disons que nous voulons répertorier tous les utilisateurs avec leurs maisons correspondantes, mais seulement si les maisons ont 3 chambres ou plus.

Puisque nous voulons garder tous les utilisateurs, nous utiliserons un OUTER JOIN, plus précisément un LEFT JOIN. Notre exigence concernant le nombre de chambres à coucher est clairement une condition de filtrage. Nous allons donc l'inclure dans la clause WHERE. Voici notre requête SQL avec les conditions spécifiées comme prévu :

SELECT u.id, u.name, h.address, h.city, h.bedrooms
FROM users u
LEFT JOIN houses h
ON u.id = h.owner_id
WHERE h.bedrooms > 2;

Cela ne semble pas correct, n'est-ce pas ? Le résultat semble être le même que si nous avions utilisé un INNER JOIN plutôt qu'un LEFT JOIN. Les utilisateurs sans maison ne sont pas inclus dans la table résultante, car ils ont NULL dans la colonne chambres à coucher lorsque les tables sont jointes. Comme les valeurs NULL sont considérées comme inférieures à 0, les lignes correspondantes sont supprimées lorsque nous appliquons la condition de filtrage - le nombre de chambres à coucher supérieur à 2.

Il existe deux solutions possibles à ce problème :

  • Ajouter une autre condition de filtrage à la clause WHERE, comme chambres à coucher est NULL:
    SELECT u.id, u.name, h.address, h.city, h.bedrooms
    FROM users u
    LEFT JOIN houses h
    ON u.id = h.owner_id
    WHERE h.bedrooms > 2 OR h.bedrooms is NULL;
    
  • Déplacer la condition de filtrage vers la clause ON:
    SELECT u.id, u.name, h.address, h.city, h.bedrooms
    FROM users u
    LEFT JOIN houses h
    ON u.id = h.owner_id AND h.bedrooms > 2;
    

L'une ou l'autre de ces requêtes nous donne le résultat suivant :



idnameaddresscitybedrooms
11Jane StewartNULLNULLNULL
12Mary CooperMayfield Road, 34Cardiff3
12Mary CooperBrook Street, 5Cardiff4
13John WatsonCromwell Road, 23LiverpoolNULL
14Christian WoodNULLNULLNULL
15William GreyNULLNULLNULL
16Brandon EvansQueen Street, 45Bristol3
17Isabella GonsalezNULLNULLNULL
18Diana TaylorNULLNULLNULL
19Luke WilsonNULLNULLNULL
20Michael LeeNULLNULLNULL

Maintenant vous savez ! Sur OUTER JOINs, la façon dont nous spécifions les conditions est importante.

Pratiquons les JOINs en SQL !

SQL JOINs n'est pas trop difficile à comprendre. Cependant, comme vous avez pu le voir dans les exemples de cet article, il y a des nuances à prendre en compte lorsque vous joignez des tables et rédigez des conditions de jointure en SQL.

Si vous voulez vraiment maîtriser Les jointures en SQL, la pratique avec des ensembles de données réels est un facteur clé de succès. Je vous recommande de commencer par le cours interactif sur les jointures SQL, qui comprend 93 défis de codage couvrant les types de jointures les plus courants, tels que JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, et même les auto-joints et les joints non égaux. Après avoir suivi ce cours, vous saurez comment joindre plusieurs tables, comment joindre des tables sans colonne commune et comment filtrer correctement les données avec différents types de JOINs.

Pour ceux qui souhaitent acquérir de l'expérience avec des cas d'utilisation encore plus nombreux sur SQL JOIN, je vous recommande de suivre la filière La pratique du SQL . Il comprend cinq cours interactifs avec plus de 600 défis de codage, couvrant non seulement les bases de Les jointures en SQL mais aussi comment filtrer l'ensemble des résultats avec une clause WHERE, comment agréger des données avec GROUP BY et HAVING, et comment utiliser des sous-requêtes, y compris des sous-requêtes corrélées. Vous allez vous amuser comme des fous !

BONUS. Voici les 10 meilleures questions d'entretien SQL JOIN avec les réponses.