Séance 6: Langage SQL

Transcription

Séance 6: Langage SQL
Séance 6: Langage SQL
INFO 0009 - Bases de données
ULg
March 16, 2015
1. Création de tables
Format général:
CREATE TABLE IF NOT EXISTS <NOM_TABLE>(
<nom_var1> <type_var1> <option_var1>,
...
<nom_varN> <type_varN> <option_varN>,
PRIMARY KEY(nom_varI),
FOREIGN KEY(nom_varJ) REFERENCES <TABLE>(<nom_var>),
...
FOREIGN KEY(nom_varK) REFERENCES <TABLE>(<nom_var>)
)ENGINE=InnoDB;
Type : INT,BIGINT,CHAR,VARCHAR,DATE,...
Options : NOT NULL, UNIQUE, PRIMARY KEY,
AUTO INCREMENT,...
Exercice 1
Créer les tables suivantes:
1. Personne(n national, nom, prenom, sexe, rue, numero, CP,
CL)
2. Commune(code postal,nom commune)
3. Localite(code postal,code localite,nom localite)
4. Mariage(code mariage, n national mari, n national femme,
date mariage, date divorce, code postal)
5. Enfant(n national enfant, n national pere, n national mere,
date naissance)
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
rue VARCHAR(50) NOT NULL,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
rue VARCHAR(50) NOT NULL,
numero VARCHAR(5) NOT NULL,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
rue VARCHAR(50) NOT NULL,
numero VARCHAR(5) NOT NULL,
code_postal INT NOT NULL,
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
rue VARCHAR(50) NOT NULL,
numero VARCHAR(5) NOT NULL,
code_postal INT NOT NULL,
code_localite INT NOT NULL
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
rue VARCHAR(50) NOT NULL,
numero VARCHAR(5) NOT NULL,
code_postal INT NOT NULL,
code_localite INT NOT NULL,
FOREIGN KEY (code_postal,code_localite)
REFERENCES Localite(code_postal,code_localite)
Création de tables: Exercice 1
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
CREATE TABLE IF NOT EXISTS Personne(
n_national BIGINT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
sexe CHAR(1) NOT NULL,
rue VARCHAR(50) NOT NULL,
numero VARCHAR(5) NOT NULL,
code_postal INT NOT NULL,
code_localite INT NOT NULL,
FOREIGN KEY (code_postal,code_localite)
REFERENCES Localite(code_postal,code_localite)
)engine=InnoDB;
Exercice 1
Créer les tables suivantes:
1. Commune(code postal,nom commune)
2. Localite(code postal,code localite,nom localite)
3. Mariage(code mariage, n national mari, n national femme,
date mariage, date divorce, code postal)
4. Enfant(n national enfant, n national pere, n national mere,
date naissance)
Commune(code postal,nom commune)
CREATE TABLE IF NOT EXISTS Commune(
code_postal INT PRIMARY KEY,
nom_commune VARCHAR(50) NOT NULL,
)ENGINE=InnoDB;
Localite(code postal,code localite,nom localite)
CREATE TABLE IF NOT EXISTS Localite(
code_postal INT NOT NULL,
code_localite INT NOT NULL,
nom_localite VARCHAR(50) NOT NULL,
PRIMARY KEY (code_postal,code_localite)
FOREIGN KEY code_postal REFERENCES Commune(code_postal)
)ENGINE=InnoDB;
ou...
CREATE TABLE IF NOT EXISTS Localite(
code_postal INT NOT NULL,
code_localite INT NOT NULL,
nom_localite VARCHAR(50) NOT NULL,
PRIMARY KEY (code_postal,code_localite)
)ENGINE=InnoDB;
ALTER TABLE Localite
ADD CONSTRAINT ‘cstr_localite_1‘ FOREIGN KEY
code_postal REFERENCES Commune(code_postal)
Mariage(code mariage, n national mari, n national femme,
date mariage, date divorce, code postal)
CREATE TABLE IF NOT EXISTS Mariage(
code_mariage INT PRIMARY KEY,
n_national_mari BIGINT NOT NULL,
n_national_femme BIGINT NOT NULL,
date_mariage DATE NOT NULL,
date_divorce DATE,
code_postal INT NOT NULL,
FOREIGN KEY code_postal
REFERENCES Commune(code_postal),
FOREIGN KEY n_national_mari
REFERENCES Personne(n_national),
FOREIGN KEY n_national_femme
REFERENCES Personne(n_national),
CONSTRAINT CHECK_DATES
CHECK (date_divorce >= date_mariage)
)ENGINE=InnoDB;
Enfant(n national enfant, n national pere, n national mere,
date naissance)
CREATE TABLE IF NOT EXISTS Enfant(
n_national_enfant BIGINT NOT NULL,
n_national_pere BIGINT,
n_national_mere BIGINT NOT NULL,
date_naissance DATE NOT NULL,
PRIMARY KEY n_national_enfant,
FOREIGN KEY n_national_enfant
REFERENCES Personne(n_national),
FOREIGN KEY n_national_mere
REFERENCES Personne(n_national),
FOREIGN KEY n_national_pere
REFERENCES Personne(n_national)
)ENGINE=InnoDB;
Requêtes
Requêtes
SELECT *
FROM <nom_table>
Sélectionne tous les tuples de la table
Requêtes
Table ETUDIANT:
Nom
Prénom
Dupont Georges
Dupont
Henri
Durant
Francis
Durant Gustave
Proviste
Alain
Age
17
16
17
17
14
Points
12
13
15
14
12
Age
17
16
17
17
14
Points
12
13
15
14
12
SELECT *
FROM ETUDIANTS
Nom
Dupont
Dupont
Durant
Durant
Proviste
Prénom
Georges
Henri
Francis
Gustave
Alain
Requêtes
SELECT <col_i>,...,<col_k>
FROM <nom_table>
Sélectionne tous les tuples de la table
Les tuples sont composés des colonnes spécifiées
Requêtes
Table ETUDIANT:
Nom
Prénom
Dupont Georges
Dupont
Henri
Durant
Francis
Durant Gustave
Proviste
Alain
SELECT Nom,Prénom
FROM ETUDIANTS
Nom
Dupont
Dupont
Durant
Durant
Proviste
Prénom
Georges
Henri
Francis
Gustave
Alain
Age
17
16
17
17
14
Points
12
13
15
14
12
Requêtes
SELECT DISTINCT *
FROM <nom_table>
DISTINCT permet de sélectionner tous les tuples différents de la
table
Requêtes
Table ETUDIANT:
Nom
Prénom
Dupont Georges
Dupont
Henri
Durant
Francis
Durant Gustave
Proviste
Alain
Age
17
16
17
17
14
SELECT DISTINCT Nom
FROM ETUDIANTS
Nom
Dupont
Durant
Proviste
Points
12
13
15
14
12
Requêtes
SELECT COUNT *
FROM <nom_table>
COUNT compte le nombre de tuples de la table
Requêtes
Table ETUDIANT:
Nom
Prénom
Dupont Georges
Dupont
Henri
Durant
Francis
Durant Gustave
Proviste
Alain
Age
17
16
17
17
14
Points
12
13
15
14
12
SELECT COUNT(DISTINCT Name)
FROM ETUDIANTS
3
(Dupont, Durant, Proviste)
Requêtes
SELECT *
FROM <nom_table>
WHERE CSTR(column)
WHERE impose des contraintes sur les tuples en fonction des
valeurs des colonnes
Requêtes
Table ETUDIANT:
Nom
Prénom
Dupont Georges
Dupont
Henri
Durant
Francis
Durant Gustave
Proviste
Alain
Age
17
16
17
17
14
Points
12
13
15
14
12
Age
17
16
Points
12
13
SELECT *
FROM ETUDIANTS
WHERE Nom="Dupont"
Nom
Dupont
Dupont
Prénom
Georges
Henri
Requêtes
SELECT *
FROM <nom_table_1> NATURAL JOIN <nom_table_2>
NATURAL JOIN est le produit cartésien entre deux tables basé sur
les noms de colonnes communs
Requêtes
TABLE ETUDIANTS:
ID
1
2
Nom
Proviste
Durant
Prénom
Alain
Georges
TABLE INTERROS:
ID
Cours
Points
1
Math
17
1
Francais
10
2 Geographie
14
2
Francais
12
SELECT *
FROM ETUDIANTS NATURAL JOIN INTERROS
ID
1
1
2
2
Nom
Proviste
Proviste
Durant
Durant
Prénom
Alain
Alain
Georges
Georges
Cours
Math
Francais
Geographie
Francais
Points
17
12
14
12
Requêtes
TABLE ETUDIANTS:
ID
1
2
Nom
Proviste
Durant
Prénom
Alain
Georges
TABLE INTERROS:
ID
Cours
Points
1
Math
17
1
Francais
10
2 Geographie
14
2
Francais
12
SELECT DISTINCT Nom,Prenom
FROM ETUDIANTS NATURAL JOIN INTERROS
WHERE Points >= 14
Nom
Proviste
Durant
Prénom
Alain
Georges
Requêtes
TABLE ETUDIANTS:
ID
1
2
Nom
Proviste
Durant
Prénom
Alain
Georges
TABLE INTERROS:
ID
Cours
Points
1
Math
17
1
Francais
10
2 Geographie
14
2
Francais
12
SELECT DISCTINCT NOM,PRENOM
FROM ETUDIANTS
WHERE ID IN
(SELECT ID FROM INTERROS
WHERE Points>=14)
Nom
Proviste
Durant
Prénom
Alain
Georges
Requêtes
SELECT *
FROM <NOM_TABLE>
GROUP BY <colonne>
GROUP BY regroupe les résultats par une ou plusieurs colonnes
Requêtes
TABLE ETUDIANTS:
Nom
Prénom
Dupont Georges
Dupont
Henri
Durant
Francis
Durant Gustave
Proviste
Alain
Age
17
16
17
17
14
Points
12
13
15
14
12
SELECT Nom, SUM(Age), AVG(Points)
FROM ETUDIANTS
GROUP BY Nom
Nom
Dupont
Durant
Proviste
SUM(Age)
33
34
14
AVG(Points)
12.5
14.5
12
Exercice 1.2
Personne(n national, nom, prenom, sexe, rue, numero, CP, CL)
Commune(code postal,nom commune)
Localite(code postal,code localite,nom localite)
Mariage(code mariage, n national mari, n national femme,
date mariage, date divorce, code postal)
Enfant(n national enfant, n national pere, n national mere,
date naissance)
(a) Nom et prénom des personnes s’étant mariées à Liège
(b) Nom et prénom des personnes sans enfants
(c) Nom et prénom des personnes nées de père inconnu
(d) Nombre de localités par communes
(e) Nom et prénom des enfants nés après le mariage de leurs
parents
(f) Pourcentage de divorces
(a) Nom et prénom des personnes s’étant mariées à Liège
SELECT DISTINCT nom, prenom
FROM Personne
WHERE n_national IN
(SELECT n_national_mari
FROM Mariage
WHERE code_postal=4000)
OR n_national IN
(SELECT n_national_femme
FROM Mariage
WHERE code_postal=4000);
(b) Nom et prénom des personnes sans enfants
SELECT DISTINCT nom, prenom
FROM Personne
WHERE n_national NOT IN
(SELECT nn
FROM
(SELECT n_national_pere AS nn
FROM Enfant)
UNION
(SELECT n_national_mere AS nn
FROM Enfant)
);
(c) Nom et prénom des personnes nées de père inconnu
SELECT DISTINCT nom, prenom
FROM Personne
WHERE n_national IN
(SELECT n_national_enfant
FROM Enfant
WHERE n_national_pere IS NULL);
(d) Nombre de localités par commune
SELECT nom_commune, COUNT(code_localite)
FROM Commune NATURAL JOIN Localite
GROUP BY code_postal
(e) Nom et prénom des enfants nés après le mariage de
leurs parents (I)
1. Sélectionner le numéro national des enfants nés après le mariage
de leurs parents
SELECT n_national_enfant
FROM Enfant e
WHERE date_naissance >
(SELECT date_mariage
FROM Mariage
WHERE n_national_mari = e.n_national_pere
AND n_national_femme = e.n_national_mere)
(e) Nom et prénom des enfants nés après le mariage de
leurs parents (II)
2. Trouver les noms et prénoms des personnes dont on a obtenu le
numéro national
SELECT nom, prenom
FROM Personne
WHERE n_national IN
(SELECT n_national_enfant
FROM Enfant e
WHERE date_naissance >
(SELECT date_mariage
FROM Mariage
WHERE n_national_mari = e.n_national_pere
AND n_national_femme = e.n_national_mere)
);
(f) Pourcentage de divorces par commune (I)
1. Nombre de mariages par code postal
SELECT code_postal, COUNT(code_mariage) AS nmariages
FROM Mariage
GROUP BY code_postal
2. Nombre de divorces par code postal
SELECT code_postal, COUNT(code_mariage) AS ndivorces
FROM Mariage
WHERE date_divorce IS NOT NULL
GROUP BY code_postal
(f) Pourcentage de divorces par commune (II)
3. Nombre de mariages et de divorces par code postal
SELECT code_postal, nmariages, ndivorces
FROM
(SELECT code_postal, COUNT(code_mariage) AS nmariages
FROM Mariage
GROUP BY code_postal)
NATURAL JOIN
(SELECT code_postal, COUNT(code_mariage) AS ndivorces
FROM Mariage
WHERE date_divorce IS NOT NULL
GROUP BY code_postal)
(f) Pourcentage de divorces par commune (III)
4. Pourcentage de divorces par commune
SELECT nom_commune, ndivorces/nmariages
FROM
SELECT code_postal, nmariages, ndivorces
FROM
(
(SELECT code_postal, COUNT(code_mariage) AS nmariages
FROM Mariage
GROUP BY code_postal)
NATURAL JOIN
(SELECT code_postal, COUNT(code_mariage) AS ndivorces
FROM Mariage
WHERE date_divorce IS NOT NULL
GROUP BY code_postal)
)
NATURAL JOIN Commune
WHERE nmariages>0
Exercice 2
Créer les tables suivantes:
1. Auteur(code auteur, nom, prenom)
2. Livre(n livre, ISBN, titre, editeur, date edition)
3. Ecrit(code auteur, n livre)
4. Exemplaire(n livre, n exemplaire, etat, date acq)
5. Emprunteur(n inscr, nom, prenom, adresse)
6. Emprunt(n livre, n exemplaire, n inscr, date empr)
Auteur(code auteur, nom, prenom)
CREATE TABLE IF NOT EXISTS Auteur(
code_auteur INT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL
)ENGINE=InnoDB;
Livre(n livre, ISBN, titre, date edition)
CREATE TABLE IF NOT EXISTS Livre(
n_livre INT PRIMARY KEY,
ISBN VARCHAR(17) NOT NULL UNIQUE,
editeur VARCHAR(50) NOT NULL,
titre VARCHAR(100) NOT NULL,
date_edition DATE NOT NULL
)ENGINE=InnoDB;
Ecrit(code auteur, n livre)
CREATE TABLE IF
code_auteur
n_livre INT
PRIMARY KEY
FOREIGN KEY
FOREIGN KEY
)ENGINE=InnoDB;
NOT EXISTS Ecrit(
INT NOT NULL,
NOT NULL,
(code_auteur,n_livre)
code_auteur REFERENCES Auteur(code_auteur),
n_livre REFERENCES Livre(n_livre)
Exemplaire(n livre, n exemplaire, etat, date acq)
CREATE TABLE IF NOT EXISTS Exemplaire(
n_livre INT NOT NULL,
n_exemplaire INT NOT NULL,
etat VARCHAR(50) NOT NULL,
date_acq DATE NOT NULL,
PRIMARY KEY (n_livre,n_exemplaire)
FOREIGN KEY n_livre REFERENCES Livre(n_livre)
)ENGINE=InnoDB;
Emprunteur(n inscr, nom, prenom, adresse)
CREATE TABLE IF NOT EXISTS Emprunteur(
n_inscr INT PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
adresse VARCHAR(200) NOT NULL,
)ENGINE=InnoDB;
Emprunt(n livre, n exemplaire, n inscr, date empr)
CREATE TABLE IF NOT EXISTS Emprunt(
n_livre INT NOT NULL,
n_exemplaire INT NOT NULL,
n_inscr INT NOT NULL,
date_empr DATE NOT NULL,
PRIMARY KEY (n_livre, n_exemplaire, n_inscr, date_empr),
FOREIGN KEY n_livre REFERENCES Livre(n_livre),
FOREIGN KEY (n_livre,n_exemplaire) REFERENCES
Exemplaire(n_livre,n_exemplaire) ,
FOREIGN KEY n_inscr REFERENCES Emprunteur(n_inscr)
)ENGINE=InnoDB;
Exercice 2.2
(a) Titres écrits par Yves Fonctionrecurs
(b) Numéros, noms et prénoms des emprunteurs qui ont en prêt
un exemplaire du livre n◦ 10
(c) Nombre d’emprunts en cours
(d) Pour chaque livre, numéros, titres et nombre d’exemplaires en
prêt
(e) Numéros et titres des livres édités depuis le 1er septembre 2003
(f) Noms, prénoms et codes des auteurs ayant écrit le plus de
livres dans la bibliothèque
(g) Numéros et titres des livre encore disponibles (il reste au
moins un exemplaire)
(h) Numéros et titres des livres dont tous les exemplaires ont été
empruntés
(i) Numéros et titres des livres disponibles édités après le 1er
septembre 2003 dont le titre contient le mot motivation.
(a) Titres écrits par Yves Fonctionrecurs
SELECT titre
FROM Auteurs NATURAL JOIN Ecrit NATURAL JOIN Livre
WHERE Nom="Fonctionrecurs" AND prenom="Yves"
(b) Numéro, nom et prénom des emprunteurs qui ont en
prêt un exemplaire du livre n◦ 10
SELECT n_inscr, nom, prenom
FROM Emprunt NATURAL JOIN Emprunteur
WHERE n_livre=10
(c) Nombre d’emprunts en cours
SELECT COUNT(*)
FROM Emprunt
(d) Pour chaque livre, numéro, titre et nombre
d’exemplaires en prêt (I)
Attention à ne pas oublier les livres qui n’ont pas été prêtés...
1. Numéro et nombre d’emprunt(s) des livres empruntés au moins
une fois
SELECT n_livre, COUNT(*) as n_empruntes
FROM Emprunt
GROUP BY n_livre
2. Numéro et nombre d’emprunt(s) des livres qui ne sont pas
empruntés
SELECT n_livre, 0 as n_empruntes
FROM Livre
WHERE n_livre NOT IN (SELECT n_livre FROM Emprunt)
(d) Pour chaque livre, numéro, titre et nombre
d’exemplaires en prêt (II)
3. Union de ces deux tables
(SELECT n_livre, COUNT(*) as n_empruntes
FROM Emprunt
GROUP BY n_livre)
UNION
(SELECT n_livre, 0 as n_empruntes
FROM Livre
WHERE n_livre NOT IN (SELECT n_livre FROM Emprunt)
(d) Pour chaque livre, numéro, titre et nombre
d’exemplaires en prêt (III)
4. NATURAL JOIN avec Livre pour récupérer le titre
SELECT n_livre, titre, n_empruntes
FROM
((SELECT n_livre, COUNT(*) as n_empruntes
FROM Emprunt
GROUP BY n_livre)
UNION
(SELECT n_livre, 0 as n_empruntes
FROM Livre
WHERE n_livre NOT IN (SELECT n_livre FROM Emprunt))
NATURAL JOIN Livre
(e) Numéros et titres des livres édités depuis le 1er
septembre 2003
SELECT n_livre, titre
FROM Livre
WHERE date_edition>=’01-09-2003’
(f) Nom, prénom et code des auteurs ayant écrit le plus de
livres dans la bibliothèque (I)
1. Trouver les livres présents en bibliothèque
SELECT DISTINCT n_livre
FROM Exemplaire
2. Obtenir le code auteur et le nombre correspondant de livres
écrits en bibliothèque
SELECT code_auteur, COUNT(n_livre) as cnt
FROM
(SELECT DISTINCT n_livre
FROM Exemplaire NATURAL JOIN Ecrit)
GROUP BY code_auteur
I
Appelons cette table T1
(f) Nom, prénom et code des auteurs ayant écrit le plus de
livres dans la bibliothèque (II)
3. Trouver le maximum de livres écrits par un auteur dans la
bibliothèque
SELECT MAX(cnt)
FROM T1
4. Rechercher les auteurs ayant au moins autant de livres...
SELECT code_auteur, cnt
FROM
T1
HAVING cnt>=
SELECT MAX(cnt)
FROM T1
(f) Nom, prénom et code des auteurs ayant écrit le plus de
livres dans la bibliothèque (III)
5. Requete finale
SELECT nom, prenom, code_auteur
FROM
((SELECT code_auteur, cnt
FROM
T1
HAVING cnt>=
SELECT MAX(cnt)
FROM T1)
NATURAL JOIN Auteur)
(g) Numéro et titre des livre encore disponible (il reste au
moins un exemplaire) (I)
1. Rechercher si un exemplaire ex particulier a été emprunté
SELECT *
FROM Emprunt
WHERE n_livre = ex.n_livre
AND n_exemplaire = ex.n_exemplaire
2. Rechercher les identifiants de livre dont un exemplaire n’a pas
été emprunté
SELECT DISTINCT n_livre
FROM Exemplaire ex
WHERE NOT EXISTS
SELECT *
FROM Emprunt
WHERE n_livre = ex.n_livre
AND n_exemplaire = ex.n_exemplaire
(g) Numéro et titre des livre encore disponible (il reste au
moins un exemplaire) (II)
3. NATURAL JOIN avec Livre pour obtenir les titres
SELECT titre, n_livre
FROM
((SELECT n_livre
FROM Exemplaire ex
WHERE NOT EXISTS
(SELECT *
FROM Emprunt
WHERE n_livre = ex.n_livre
AND n_exemplaire = ex.n_exemplaire))
NATURAL JOIN Livre)
(h) Numéro et titre des livres dont tous les exemplaires ont
été empruntés (I)
On cherche l’inverse de la question précédente!
1. Rechercher les identifiants de livres disponibles
SELECT DISTINCT n_livre
FROM Exemplaire ex
WHERE NOT EXISTS
SELECT *
FROM Emprunt
WHERE n_livre = ex.n_livre
AND n_exemplaire = ex.n_exemplaire
(h) Numéro et titre des livres dont tous les exemplaires ont
été empruntés (II)
2. Chercher les livres qui ne sont pas présents dans cette table.
SELECT titre, n_livre
FROM Livre l
WHERE NOT IN
(SELECT DISTINCT n_livre
FROM Exemplaire ex
WHERE ex.n_livre = l.n_livre AND
NOT EXISTS
(SELECT *
FROM Emprunt
WHERE n_livre = ex.n_livre
AND n_exemplaire = ex.n_exemplaire))
(i) Numéro et titre des livres disponibles édités après le 1er
septembre 2003 dont le titre contient le mot motivation.
Encore très semblable à (g)...
SELECT titre, n_livre
FROM
((SELECT n_livre
FROM Exemplaire ex
WHERE NOT EXISTS
(SELECT *
FROM Emprunt
WHERE n_livre = ex.n_livre
AND n_exemplaire = ex.n_exemplaire))
NATURAL JOIN Livre)
WHERE date_edition>’01-09-2003’
AND titre LIKE ’%motivation%’