Retrouver les numéros et le nom des producteurs qui produisent au moins tous les vins produits par le producteur 35

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.NOM

From 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.NOM

From 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.NOM

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)

Ici, 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).