Pas exactement. Ce serait peut-être plus clair si nous reformattions légèrement la requête de @simon :
SELECT
cu.*,
ue.email
FROM category_users cu
JOIN user_emails ue ON ue.user_id = cu.user_id
WHERE (category_id = '10' AND ue.primary = true)
Les conditions category_id et ue.primary font toutes deux partie de la clause WHERE, reliées par AND. Si vous supprimez l’une des conditions, vous supprimez le AND, mais vous conservez la clause WHERE.
La plupart des requêtes SQL simples suivent cette forme :
SELECT <choses_désirées>
FROM <tables>
WHERE <conditions_de_filtrage>
Vous pouvez omettre la clause WHERE entièrement, mais dans ce cas, vous obtiendrez toutes les lignes des tables que vous avez spécifiées.
Voici votre requête originale (reformatée) :
SELECT *
FROM category_users
WHERE category_id = '10'
-
“SELECT *” signifie que vous souhaitez que la requête renvoie toutes les colonnes de toutes les tables impliquées.
-
“FROM category_users” indique la table que vous souhaitez interroger. La table category_users contient des lignes ressemblant à ceci :
| id |
category_id |
user_id |
notification_level |
| 1 |
1 |
1 |
3 |
| 2 |
1 |
2 |
3 |
| 3 |
3 |
1 |
3 |
category_id et user_id sont appelés clés étrangères car elles pointent vers une ligne dans une autre table (dans ce cas, les tables categories et users). Ainsi, les 3 lignes ci-dessus signifient que l’utilisateur avec l’ID 1 surveille les catégories 1 et 3, et que l’utilisateur avec l’ID 2 surveille la catégorie 1. Le notification_level indique s’ils sont en mode Surveillance, Surveillance du premier message ou Suivi.
-
“WHERE category_id = '10'” signifie que vous n’êtes intéressé que par les lignes où la valeur dans la colonne category_id est 10. Sans cette ligne, vous obtiendriez toutes les lignes de la table category_users.
@simon vous a fourni une nouvelle version qui ajoute l’adresse e-mail de l’utilisateur :
Cette requête a apporté quelques modifications par rapport à votre version originale, pour deux raisons : les adresses e-mail sont stockées dans une table différente (la table user_emails), et les utilisateurs peuvent avoir plusieurs adresses e-mail.
-
Dans la clause SELECT :
- “
cu.*” signifie « toutes les colonnes de la table cu »
- “
ue.email” signifie « la colonne email de la table ue »
-
Dans la clause FROM :
-
La table category_users possède maintenant un alias, “cu”, ce qui évite de taper à nouveau si vous devez y faire référence plusieurs fois.
-
Nous avons JOINé la table user_emails et lui avons donné l’alias ue.
La table user_emails contient des lignes comme celle-ci :
Cela signifie que l’utilisateur avec l’ID 1 a 2 adresses e-mail : alex@example.com (l’adresse principale) et alex@other.example.com (une adresse secondaire). L’utilisateur avec l’ID 2 n’a qu’une seule adresse.
Lorsque vous JOINez 2 tables en SQL, vous devez généralement indiquer à la base de données quelle est la condition de jointure. Si vous ne le faites pas, la base de données ne sait pas quelles valeurs dans chacune des tables doivent correspondre, et vous vous retrouverez avec toutes les combinaisons possibles de lignes des 2 tables. Si vous écriviez cette requête :
SELECT *
FROM category_users
JOIN user_emails
…avec les données d’exemple ci-dessus, vous obtiendriez 9 lignes : vous obtiendriez la première ligne de category_users trois fois, une fois avec chacune des lignes de user_emails, puis de même pour la deuxième ligne de category_users trois fois, et enfin la troisième ligne de category_users trois fois.
La condition de jointure indique généralement à la base de données quelle colonne dans les 2 tables représente la même valeur. Dans ce cas, les colonnes category_users.user_id et user_emails.user_id représentent toutes deux la même valeur. En écrivant ON ue.user_id = cu.user_id après JOIN user_emails ue, nous indiquons à la base de données d’apparier les lignes de user_emails avec les lignes appropriées de category_users.
-
Même avec la condition de jointure, nous obtiendrons toujours 4 lignes pour l’utilisateur avec l’ID 1, car il surveille 2 catégories et possède 2 adresses e-mail : nous obtiendrons une ligne pour chaque combinaison. @simon a donc ajouté une condition supplémentaire à la clause WHERE afin que la requête ne renvoie que les lignes avec l’adresse e-mail principale de l’utilisateur. Cette condition s’ajoute en plus de la condition déjà existante (restriction de l’ID de catégorie) : pour être renvoyées, les lignes doivent avoir category_id = '10' ET ue.primary = true.
Ensuite, comme vous ne souhaitiez pas limiter votre recherche à une seule catégorie, vous avez simplement dû supprimer le filtre category_id. Vous ne voulez pas supprimer toute la clause WHERE, car vous souhaitez toujours ne renvoyer que les adresses e-mail principales. En d’autres termes, votre condition de filtrage est passée de :
category_id = '10' AND ue.primary = true
à
ue.primary = true
Ouf ! J’espère que tout cela est clair 