Bonsoir,
Envoyé par
witch
1 2 3
| Select E.Personne From Emprunt E
Except
Select R.Personne from Retard R Where E.Personne=R.personne |
Que ce soit en SQL ou autre langage, WHERE n’a pas à figurer ici (il redonde et en plus syntaxiquement il provoque une erreur), EXCEPT suffit :
1 2 3
| SELECT Personne FROM EMPRUNT
EXCEPT
SELECT Personne FROM RETARD ; |
Envoyé par
witch
1 2 3
| Select E.Personne From Emprunt
where E.Personne not exists in ( Select D.Personne from Retard R
Where D.Personne=R.Personne ) |
La syntaxe exacte est la suivante :
1 2 3 4 5
| SELECT DISTINCT Personne
FROM EMPRUNT
WHERE NOT EXISTS (SELECT *
FROM RETARD
WHERE EMPRUNT.Personne = RETARD.Personne) ; |
Envoyé par
witch
je ne comprends pas ce que veut dire ensembliste, et non relationnelle, d'autant que je ne comprends pas le rôle du distinct dans cette requête, le distinct n'est pas représenté dans la formule que j'ai cité avant, si ?
Pacmann a parfaitement raison. Ce que j'écris doublonne (sic !) avec ce qu’il vous a exposé, mais parfois bis repetita placent...
Par définition, les éléments appartenant à un ensemble n’y doublonnent pas. L’ensemble N des entiers naturels est le suivant :
{0, 1, 2, 3, ...}
mais ça n’est pas un sac à l'instar de cette chose bizarre :
{0, 0, ..., 1, 1, 1, ..., 2, 2, ...}
Selon la théorie relationnelle, EMPRUNT et RETARD sont des variables prenant des valeurs qui sont des relations. L’en-tête d’une variable ou d’une relation est un ensemble au sens de la théorie des ensembles. En SQL ça n’est pas le cas et vous avez le droit d’écrire quelque chose comme ceci (ce qui est interdit en relationnel) :
1 2 3
| SELECT Personne, Personne, Personne, ...
FROM EMPRUNT
... |
Par contre, l’en-tête de la variable EMPRUNT est valide :
{Personne, Livre, DateEmprunt, DateRetourPrevue, DateRetourEffective}.
Même chose pour l’en-tête de la relation EMPRUNT ci-dessous. De la même façon, le corps de cette relation (l’ensemble de ses n-uplets, ou lignes) est un ensemble et aucun n-uplet ne peut y figurer en double :
1 2 3 4 5 6
| EMPRUNT {Personne, Livre, DateEmprunt, DateRetourPrevue, DateRetourEffective}
p1 l1 2011-03-11 2011-04-05 2011-09-05
p1 l1 2011-10-11 2011-11-01 2011-10-21
p1 l2 2011-10-11 2011-11-10 2011-11-10
p2 l1 2011-11-03 2011-11-07 2011-11-07
p2 l2 2011-11-05 2011-11-09 2011-11-09 |
Comme l’a montré Pacmann, SQL permet pour sa part que le corps d’une table soit un sac au lieu d’être un ensemble. Si vous omettez la clause DISTINCT et écrivez :
1 2 3 4 5
| SELECT Personne
FROM EMPRUNT
WHERE NOT EXISTS (SELECT *
FROM RETARD
WHERE EMPRUNT.Personne = RETARD.Personne) ; |
Et si la variable RETARD prend par exemple la valeur suivante :
1 2
| RETARD {Personne, Livre, DateEmprunt, PenaliteRetard}
p1 l1 2011-03-11 50 |
alors le résultat de l’opération de projection (SELECT Personne) n’est pas un ensemble mais un sac :
Si vous comptez les lignes du résultat, peut-être concluerez-vous que deux personnes ont rendu des livres en retard, vous pourriez effectuer des cumuls de pénalités erronés, etc.
Remarque
Avec les ensembles que sont les relations, le principe de fermeture est respecté, c'est-à-dire qu’on peut utiliser les yeux fermés le résultat d’une opération comme opérande pour une nouvelle opération :
Le bébé, fruit du mariage de deux relations par UNION, DIFFÉRENCE, JOINTURE, etc., est une relation qui a son tour peut être mariée et avoir des bébés de même nature que ses parents. Le problème avec les sacs est qu’il y a un risque à les faire participer à des opérations ensemblistes : unpredictable results...
Partager