La division relationnelle? mais c'est très simple!



Considérons une relation V de vins de schéma :
SQL> desc V
 Name                            Null?    Type
 ------------------------------- -------- ----
 CRU                                      VARCHAR2(30)
 MILL                                     NUMBER(4)
et les deux relations C et M construites comme projections de V respectivement sur CRU et MILL :
SQL> create view C as select distinct CRU from V;
View created.
SQL> desc C
 Name                            Null?    Type
 ------------------------------- -------- ----
 CRU                                      VARCHAR2(30)
SQL> create view M as select distinct MILL from V;
View created.
SQL> desc M
 Name                            Null?    Type
 ------------------------------- -------- ----
 MILL                                     NUMBER(4)
et demandons-nous : Quels sont les CRUs de vins existant dans TOUS les MILLésimes ?

Le résultat Q de cette question est très exactement le quotient de V divisé par M, et son schéma (son "intention") est le même que celui de C, c'est à dire le schéma du dividende V moins le schéma du diviseur M, par contre ses tuples (son "extension") sont moins nombreux que ceux de C car, bien sûr, tous les CRUs ne satisfont pas la condition !

Q est inclus dans C
D'où l'idée de soustraire de C une relation S, de même schéma CRU, dont les tuples sont les CRUs n'apparaissant PAS dans TOUS les MILLésimes.

Par ailleurs on remarque que le produit cartésien C x M peut servir à créer une relation "maximale" où TOUS les CRUs apparaîtraient dans TOUS les MILLésimes et que le complément de R par rapport à cette relation, soit C x M - R, ne contient AUCUN des tuples recherchés.

On en déduit la relation S :

SQL> create view S as
  2  select distinct CRU from
  3  (select C.CRU, M.MILL from C,M
  4   minus
  5   select CRU, MILL from V)
  6  ;

View created.
et le résultat Q recherché :
select * from C
minus
select * from S;
ou
select distinct CRU from V
minus
select distinct CRU from
      (select C.CRU, M.MILL from C,M
       minus
       select CRU, MILL from V)
;
On pourra faire l'exercice sur les données de la BD du TP à la condition...
... de créer au moins un vin satisfaisant cette requête ;-)
SQL> create sequence NUMV start with 110;

Sequence created.
SQL> insert into V
  2  select NUMV.nextval, 'Rioja', MILL, 13 from M;
23 rows created.

by saglio@enst.fr, last update: 2001/10/29