Bonjour,
Une remarque :
L’intersection équivaut à un ET au sens de la logique. Mais s’il faut obtenir l’ensemble des utilisateurs qui pratiquent Le billard à 3 bandes, le tennis et le foot, il faudra utiliser une requête comportant un bloc INTERSECT supplémentaire. Si l’on part sur la base de N sports pratiqués, on devra coder N-1 blocs INTERSECT.
On peut procéder autrement que par intersection, en effectuant ce que l’on appelle une division relationnelle. L’opérateur DIVIDEBY de l’algèbre relationnelle ne fait pas partie du langage SQL, mais on sait le paraphraser.
Partons de l’énoncé :
Des trois sports : tennis, billard à 3 bandes et foot, le joueur x les pratique tous.
Pour l’exprimer en SQL (en utilisant EXISTS), on peut écrire de façon équivalente :
Des trois sports : tennis, billard à 3 bandes et foot, il n’en existe pas que le joueur x ne pratique pas.
Pour obtenir l’ensemble des joueurs tels que x et mettre en œuvre la double négation figurant dans ce 2e énoncé, on utilise en conséquence un double NOT EXISTS :
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
SELECT UserNom
FROM USERX AS x
WHERE NOT EXISTS
(SELECT *
FROM SPORT AS y
WHERE y.SportNom IN ('Tennis', 'Billard 3 bandes', 'Foot')
AND NOT EXISTS
(SELECT *
FROM USER_SPORT AS z
WHERE x.UserId = z.UserId
AND y.SportId = z.SportId
)
) ; |
Bien sûr, si la liste des sports change, il faut modifier la requête, mais c’est à un seul endroit et de façon légère.
Si cette liste figure dans une table à part, appelons-la LISTE_SPORTS, alors la requête n’a jamais à être modifiée :
1 2 3 4 5 6 7 8 9 10 11 12 13
|
SELECT UserNom
FROM USERX AS x
WHERE NOT EXISTS
(SELECT *
FROM LISTE_SPORTS AS y
WHERE NOT EXISTS
(SELECT *
FROM USER_SPORT AS z
WHERE x.UserId = z.UserId
AND y.SportId = z.SportId
)
) ; |
Partager