Sie sind auf Seite 1von 5

Exercice 1

1. Les instruction SQL de création de tables :


– CREATE TABLE commune (
code postal INT PRIMARY KEY,
nom commune VARCHAR(20) NOT NULL) ;
– CREATE TABLE localite(
code postal INT REFERENCES commune (code postal),
code localite INT,
nom localite VARCHAR(20) NOT NULL,
PRIMARY KEY (code postal, code localite)) ;
– CREATE TABLE personne(
numero national INT PRIMARY KEY,
nom VARCHAR(20) NOT NULL,
prenom VARCHAR(30) NOT NULL,
sexe bool NOT NULL,
rue VARCHAR(50) NOT NULL,
numero INT NOT NULL,
code postal INT REFERENCES commune(code postal),
code localite INT REFERENCES localite(code localite)) ;
– CREATE TABLE mariage(
code mariage INT PRIMARY KEY,
numero national mari INT REFERENCES personne(numero national),
numero national femme INT REFERENCES personne(numero national),
date mariage DATE NOT NULL,
date divorce DATE,
code postal INT NOT NULL
– CREATE TABLE enfant(
numero national enfant INT PRIMARY KEY,
numero national mere INT REFERENCES personne (numero national),
numero national pere INT,
date naissance DATE NOT NULL,
FOREIGN KEY (numero national enfant)
REFERENCES personne (numero national)) ;

2. Les instruction exprimant les requêtes :

(a) SELECT nom, prenom


FROM personne
WHERE numero national IN (
SELECT numero national mari
FROM mariage
WHERE code postal IN (
SELECT code postal
FROM commune
WHERE nom commune = ”Liège” )
UNION
SELECT numero national femme
FROM mariage
WHERE code postal IN (
SELECT code postal
FROM commune
WHERE nom commune = ”Liège” ))
(b) SELECT nom, prenom
FROM personne
WHERE numero national NOT
IN (
SELECT numero national mere
FROM enfant
UNION SELECT numero national pere
FROM enfant
WHERE numero national pere IS NOT NULL) ;
Voici une alternative utilisant NOT EXISTS :
SELECT nom, prenom
FROM personne
WHERE numero national NOT
EXISTS (
SELECT *
FROM enfant
WHERE personne.numero national = enfant.numero national mere
UNION SELECT *
FROM enfant
WHERE numero national pere IS NOT NULL
AND personne.numero national = enfant.numero national pere) ;

(c) SELECT m2.code postal, m1.count / ( m2.count + m1.count )


FROM (
SELECT code postal, count( code mariage ) AS ”count”
FROM mariage
WHERE date divorce IS NOT NULL
GROUP BY code postal
)m1, (
SELECT code postal, count( code mariage ) AS ”count”
FROM mariage
WHERE date divorce IS NULL
GROUP BY code postal
)m2
WHERE m2.code postal = m1.code postal
UNION
SELECT code postal, 0 / count( code mariage ) AS ”count”
FROM mariage
WHERE code postal NOT IN (
SELECT code postal
FROM mariage
WHERE date divorce IS NOT NULL
)
GROUP BY code postal ;

(d) SELECT nom, prenom


FROM personne
WHERE numero national
IN (
SELECT numero national enfant
FROM enfant
WHERE numero national pere IS NULL) ;
(e) SELECT count(code localite), nom commune
FROM commune, localite
WHERE commune.code postal = localite.code postal
GROUP BY nom commune

(f) SELECT nom, prenom


FROM personne
WHERE numero national
IN (
SELECT numero national enfant
FROM enfant
WHERE date naissance > (
SELECT date mariage
FROM mariage
WHERE numero national mere = numero national femme
AND numero national pere = numero national mari )) ;

Exercice 2
1. Les instructions SQL de création de tables :
2. Les instruction exprimant les requêtes :
(a) SELECT titre
FROM auteur
INNER JOIN ecrit ON auteur.code auteur = ecrit.code auteur
INNER JOIN livre ON ecrit.no livre = livre.no livre
WHERE nom auteur = ”Fonctionrecurs” AND prenom auteur = ”Yves” ;

(b) SELECT nom empr, prenom empr


FROM emprunteur
INNER JOIN emprunt ON emprunteur.no inscr = emprunt.no inscr
WHERE no livre =10 ;

(c) SELECT count(*) AS count


FROM emprunt ;

(d) SELECT livre.no livre, titre, count( * ) AS count no pret par livre
FROM livre
INNER JOIN emprunt ON livre.no livre = emprunt.no livre
GROUP BY livre.no livre

(e) SELECT livre.no livre, titre


FROM livre
WHERE date edition > ”2003-09-01”
(f) CREATE TEMPORARY TABLE nb livres
SELECT auteur.code auteur, auteur.nom auteur, auteur.prenom auteur,
count( * ) AS nb
FROM auteur
INNER JOIN ecrit ON auteur.code auteur = ecrit.code auteur
GROUP BY auteur.code auteur, auteur.nom auteur, auteur.prenom auteur
ORDER BY nb DESC , auteur.code auteur ;

CREATE TEMPORARY TABLE max nb livres


SELECT max( nb ) AS nb
FROM nb livres ;

SELECT nb livres.code auteur, nb livres.nom auteur, nb livres.prenom auteur,


nb livres.nb
FROM nb livres
INNER JOIN max nb livres ON nb livres.nb = max nb livres.nb

(g) SELECT DISTINCT livre.no livre, livre.titre


FROM livre
INNER JOIN exemplaire ON livre.no livre = exemplaire.no livre
WHERE (exemplaire.no livre, exemplaire.no exempl)
NOT IN (
SELECT no livre, no exempl
FROM emprunt) ;

Solution avec une table temporaire :


CREATE TEMPORARY TABLE pas emprunt
SELECT exemplaire.no livre, exemplaire.no exempl
FROM exemplaire
LEFT JOIN emprunt ON exemplaire.no livre = emprunt.no livre AND
exemplaire.no exempl = emprunt.no exempl
WHERE emprunt.no livre IS NULL ;

SELECT DISTINCT livre.no livre, livre.isbn, livre.titre


FROM livre
INNER JOIN exemplaire ON livre.no livre = exemplaire.no livre
INNER JOIN pas emprunt ON exemplaire.no livre = pas emprunt.no livre ;

(h) SELECT l.titre, l.no livre


FROM (
SELECT titre, livre.no livre, count( * ) AS nb
FROM livre
INNER JOIN exemplaire ON livre.no livre = exemplaire.no livre
GROUP BY livre.no livre
)l, (
SELECT no livre, count( * ) AS nb
FROM emprunt
GROUP BY no livre
)e
WHERE l.nb = e.nb
AND l.no livre = e.no livre ;
Cette requête peut être faite avec un INNER JOIN (et sans WHERE), mais aussi compètement
autrement avec une table temporaire.
(i) SELECT DISTINCT livre.no livre, livre.titre
FROM livre
INNER JOIN exemplaire ON livre.no livre = exemplaire.no livre
WHERE (exemplaire.no livre, exemplaire.no exempl)
NOT IN (
SELECT no livre, no exempl
FROM emprunt)
AND livre.date edition >= ”1998-01-01”
AND livre.titre LIKE ”%motivation%” ;