Servir(Bar, Bière)
Fréquenter(Buveur, Bar)
Aimer(Buveur, Bière)
Q1 - Les bars qui servent
une bière appréciée par 'Dupont'
Q2 - Les buveurs qui vont
dans les mêmes bars que Dupont
Q3 - Les buveurs qui fréquentent
au moins un bar où l'on sert une bière qu'ils aiment
Q4 - Les buveurs qui ne fréquentent aucun
bar où l'ont sert une bière qu'ils aiment
Q5 - Les buveurs qui fréquentent tous les
bars
Q6 - Les buveurs qui fréquentent tous les
bars qui servent au moins une bière qu'ils aiment
Q7 - Les buveurs qui ne fréquentent que
les bars qui servent une bière qu'ils aiment
Q8 - Donner pour chaque
buveur, le nombre de bars servant une bière qu'ils aiment
Q9 - Les buveurs qui fréquentent
au moins 2 bars où l'on sert une bière qu'ils aiment
Calcul Relationnel des T uples (CRT)
{b:Bar / EXISTS s FROM Servir, EXISTS a FROM Aimer, s.Bière = a.Bière AND a.Buveur = 'Dupont' AND b = s.Bar}
SQL>
SELECT Bar
FROM Aimer A, Servir S
WHERE S.Bière = A.bière AND Buveur ='Dupont';

CRT
{b:Buveur / EXISTS f1 FROM Fréquenter, EXISTS f2 FROM Fréquenter, f1.Bar = f2.Bar AND f1.Buveur = 'Dupont' AND f2.Buveur = b}
SQL>
SELECT F1.Buveur
FROM Fréquenter F1, Fréquenter F2
WHERE F1.Bar = F2.Bar AND F2.Buveur = 'Dupont';

CRT
{b:Buveur / EXISTS f FROM Fréquenter, EXISTS s FROM Servir, EXISTS a FROM Aimer, a.Bière = s.Bière ANDs.Bar = f.Bar AND f.Buveur = a.buveur AND f.Buveur = b}
SQL>
SELECT F.Buveur
FROM Fréquenter F, Aimer A, Servir S
WHERE A.Bière = S.Bière AND S.Bar = F.Bar AND A.Buveur = F.Buveur ;

CRT
{b:Buveur / WHICHEVER f FROM Fréquenter, f.buveur = b => (WHICHEVER s FROM Servir, WHICHEVER a FROM Aimer, a.Bière != s.Bière OR s.Bar != f.Bar OR f.Buveur != a.buveur}
Règles de transformation pour passer à la formulation SQL :
- A => B est équivalent à NOT A OR B
{b:Buveur / WHICHEVER f FROM Fréquenter, f.Buveur = b => (WHICHEVER s FROM Servir, WHICHEVER a FROM Aimer, a.Bière != s.Bière OR s.Bar != f.Bar OR f.Buveur != a.Buveur)}
- Eliminer WHICHEVER à l'aide de :
- Un niveau d'imbrication avec "NOT IN" pour chaque
NOT EXISTS x .
{b:Buveur / NOT EXISTS f FROM Fréquenter, f.buveur = b AND NOT EXISTS s FROM Servir, NOT EXISTS a FROM Aimer, (a.Bière = s.Bière AND s.Bar = f.Bar AND f.Buveur = a.buveur)}
SELECT Buveur
FROM Fréquenter F
WHERE Buveur NOT IN(SELECT Buveur
FROM Aimer A, Servir S
WHERE S.Bar = F.Bar
AND S.Bière = A.Bière );
Algèbre

CRT
{b:Buveur / WHICHEVER f1 FROM Fréquenter, EXISTS f2 FROM Fréquenter, f2.Bar = f1.Bar AND f2.Buveur = b}
Elimination de WHICHEVER
{b:Buveur / NOT EXISTS f1 FROM Fréquenter, NOT EXISTS f2 FROM Fréquenter, (f2.Bar = f1.Bar AND f2.Buveur = b)}
SQL>
(SELECT F1.Buveur
FROM Fréquenter F1, Fréquenter F2
WHERE F1.Buveur NOT IN);(SELECT Buveur
FROM Fréquenter
WHERE Bar=F2.Bar)

{b:Buveur / WHICHEVER a FROM Aimer, WHICHEVER s FROM Servir, s.Bière = a.Bière AND a.Buveur = b => EXISTS f FROM Fréquenter, f.Bar = s.Bar AND f.Buveur = b }
Transformation
{b:Buveur / NOT EXISTS a FROM Aimer, NOT EXISTS s FROM Servir, (s.Bière = a.Bière AND a.Buveur = b AND NOT EXISTS f FROM Fréquenter, (f.Bar = s.Bar AND f.Buveur = b)) }
REM La requête en SQL revient à rechercher le complémentaire des buveurs qui ne fréquentent pas au moins un bar qui sert une bière qu'ils aiment:
NON(les buveurs qui ne fréquentent pas au moins un bar qui sert une bière qu'ils aiment)
SQL>
SELECT Buveur
FROM Fréquenter F
WHERE Buveur NOT IN(SELECT A.Buveur
FROM Servir S, Aimer A
WHERE S.Bière=A.Bière
AND A.Buveur NOT IN);(SELECT Buveur
FROM Fréquenter
WHERE Bar=S.Bar)

CRT
{b:Buveur / WHICHEVER f FROM Fréquenter, f.Buveur = b => EXISTS a FROM Aimer, EXISTS s FROM Servir, s.Bière = a.Bière AND f.Bar = s.Bar }
Transformation
{b:Buveur / NOT EXISTS f FROM Fréquenter,
(f.Buveur = b AND NOT EXISTS a FROM Aimer, NOT EXISTS s FROM Servir, (s.Bière
= a.Bière AND f.Bar = s.Bar)) }
REM La requête revient à rechercher le complémentaire
des buveurs qui fréquentent au moins un bar qui ne sert aucune bière
qu'ils aiment :
NON (les buveurs qui fréquentent au
moins un bar qui ne sert aucune bière qu'ils aiment)
SQL>
SELECT BuveurCe qui est équivalent à
FROM Fréquenter
WHERE Buveur NOT IN(SELECT Buveur
FROM Fréquenter F
WHERE Bar NOT IN);(SELECT Bar
FROM Servir S, Aimer A
WHERE A.Buveur = F.Buveur
And S.Bière = A.Bière)
SELECT Buveur
FROM Fréquenter
WHERE Buveur NOT IN(SELECT Buveur
FROM Fréquenter F
WHERE Buveur NOT IN);(SELECT Buveur
FROM Servir S, Aimer A
WHERE S.Bar = F.Bar
And S.Bière = A.Bière)

SQL>
SELECT Buveur, COUNT(DISTINCT Bar)
FROM Servir S, Aimer A
WHERE S.Bière = A.Bière
GROUP BY Buveur;
SQL>
SELECT Buveur
FROM Servir S, Aimer A, Fréquenter F
WHERE S.Bière = A.Bière AND A.Buveur = F.Buveur AND F.Bar = S.Bar
GROUP BY Buveur
HAVING COUNT(Bar)>2;