Retrouver les noms des producteurs qui produisent tous les vins


De manière logique cette requête peut s'écrire :
{p.nom / p IN PRODUCTEURS (QQSOIT v IN VINS (ILEXISTE r IN RECOLTES
(r.nvin=v.num et p.num=r.nprod))) }
le quantificateur QQSOIT n'existe pas en SQL, il faut transformer cette expression :
QQSOIT x IN X (P(x)) <=> NOT ILEXISTE x in X NOT(P(x))
soit pour notre exemple :
{p.nom / p IN PRODUCTEURS (NOT ILEXISTE v IN VINS (NOT ILEXISTE r IN RECOLTES
(r.nvin=v.num et p.num=r.nprod))) }
On peut maintenant exprimer cette expression en SQL :


  Select NOM

From PRODUCTEURS P

Where Not Exists ( Select *

From VINS V

Where Not Exists ( Select *

From RECOLTES R

Where R.NPROD = P.NUM and

R.NVIN = V.NUM ) )

Nombre de tuples : 0

Autre formulation :


Select P.NOM

From PRODUCTEURS P, RECOLTES R

Where NPROD=NUM

Group by P.NUM, P.NOM

Having count(*) = (Select count(*) From VINS)

Attention, cette formulation n'est possible que parce que l'ensemble des vins produits par un producteur est forcément inclus ou égal dans l'ensemble des vins. On peut donc montrer l'égalité des deux ensembles par égalité des cardinalités.