De manière logique cette requête peut s'écrire :
{p.num, p.nom / p IN PRODUCTEURS (QQSOIT r1 IN RECOLTES (ILEXISTE r2 IN RECOLTES2
(p1.num != 35 et r1.nprod = 35 et r1.nvin=r2.nvin et p.num=r2.nprod))) }
le quantificateur QQSOIT n'existe pas en SQL, il faut transformer cette expressi
on :
QQSOIT x IN X (P(x)) <=> NOT ILEXISTE x in X NOT(P(x))
soit pour notre exemple :
{p.num, p.nom / p IN PRODUCTEURS (NOT ILEXISTE r1 IN RECOLTES (NOT ILEXISTE r2 IN RECOLTES
(p1.num != 35 et r1.nprod = 35 et r1.nvin=r2.nvin et p.num=r2.nprod))) }
On peut maintenant exprimer cette expression en SQL (avec quelques réarrangements) :
Select P.NUM, P.NOMFrom PRODUCTEURS P
Where P.NUM <> 35 and
Not Exists ( Select *
From RECOLTES R1
Where R1.NPROD = 35 and
Not Exists ( Select *
From RECOLTES R2
Where R2.NPROD = P.NUM and
R2.NVIN = R1.NVIN ) )
Nombre de tuples : 4
Autre formulation ;
Select P.NUM, P.NOMFrom PRODUCTEURS P, RECOLTES R1, RECOLTES R2
Where R2.NPROD=35 and R1.NVIN=R2.NVIN and R1.NPROD<>35 and R1.NPROD=P.NUM
Group By P.NUM, P.NOM
Having Count(*) = (Select Count(*) From RECOLTES Where NPROD=35)
ou bien alors
Select P.NUM, P.NOMIci, comme l'ensemble des vins d'un producteur n'est pas forcément inclus dans l'ensemble des vins du producteur de numéro 35, on calcule l'intersection des productions d'un producteur avec celles du producteur 35. C'est cette intersection dont on compare la taille avec celle de l'ensemble des vins du producteur 35 (on s'est ramené à une inclusion des ensembles).From PRODUCTEURS P, RECOLTES R
Where P.NUM = R.NPROD and P.NUM<>35 and
R.NVIN IN (Select R2.NVIN From RECOLTES R2 Where R2.NPROD = 35)
Group By P.NUM, P.NOM
Having Count(*) = (Select Count(*) From RECOLTES Where NPROD = 35)