Re-re-re-représentation de représentants (épisode ultime)
[1 h]
Soit la base de données suivante :
REPRESENTANTS (#NR, NOMR, VILLE)
PRODUITS (#NP, NOMP, COUL, PDS)
CLIENTS (#NC, NOMC, VILLE)
VENTES (#NR=>REPRESENTANTS(NR), #NP=>PRODUITS(NP), #NC=>CLIENTS(NC), QT)
/* Les requêtes peuvent être testées dans un SGBDR, en créant une base de données avec le script SQL suivant */
/*
DROP TABLE VENTES ;
DROP TABLE CLIENTS ;
DROP TABLE PRODUITS ;
DROP TABLE REPRESENTANTS ;
*/
CREATE TABLE REPRESENTANTS (
NR INTEGER PRIMARY KEY,
NOMR VARCHAR,
VILLE VARCHAR
);
CREATE TABLE PRODUITS (
NP INTEGER PRIMARY KEY,
NOMP VARCHAR,
COUL VARCHAR,
PDS INTEGER
);
CREATE TABLE CLIENTS (
NC INTEGER PRIMARY KEY,
NOMC VARCHAR,
VILLE VARCHAR
);
CREATE TABLE VENTES (
NR INTEGER REFERENCES REPRESENTANTS(NR),
NP INTEGER REFERENCES PRODUITS(NP),
NC INTEGER REFERENCES CLIENTS(NC),
QT INTEGER,
PRIMARY KEY (NR, NP, NC)
);
INSERT INTO REPRESENTANTS (NR, NOMR, VILLE) VALUES (1, 'Stephane', 'Lyon');
INSERT INTO REPRESENTANTS (NR, NOMR, VILLE) VALUES (2, 'Benjamin', 'Paris');
INSERT INTO REPRESENTANTS (NR, NOMR, VILLE) VALUES (3, 'Leonard', 'Lyon');
INSERT INTO REPRESENTANTS (NR, NOMR, VILLE) VALUES (4, 'Antoine', 'Brest');
INSERT INTO REPRESENTANTS (NR, NOMR, VILLE) VALUES (5, 'Bruno', 'Bayonne');
INSERT INTO PRODUITS (NP, NOMP, COUL, PDS) VALUES (1, 'Aspirateur', 'Rouge', 3546);
INSERT INTO PRODUITS (NP, NOMP, COUL, PDS) VALUES (2, 'Trottinette', 'Bleu', 1423);
INSERT INTO PRODUITS (NP, NOMP, COUL, PDS) VALUES (3, 'Chaise', 'Blanc', 3827);
INSERT INTO PRODUITS (NP, NOMP, COUL, PDS) VALUES (4, 'Tapis', 'Rouge', 1423);
INSERT INTO CLIENTS (NC, NOMC, VILLE) VALUES (1, 'Alice', 'Lyon');
INSERT INTO CLIENTS (NC, NOMC, VILLE) VALUES (2, 'Bruno', 'Lyon');
INSERT INTO CLIENTS (NC, NOMC, VILLE) VALUES (3, 'Charles', 'Compiègne');
INSERT INTO CLIENTS (NC, NOMC, VILLE) VALUES (4, 'Denis', 'Montpellier');
INSERT INTO CLIENTS (NC, NOMC, VILLE) VALUES (5, 'Emile', 'Strasbourg');
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (1, 1, 1, 1);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (1, 1, 2, 1);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (2, 2, 3, 1);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (4, 3, 3, 200);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 4, 2, 190);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (1, 3, 2, 300);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 1, 2, 120);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 1, 4, 120);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 4, 4, 2);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 1, 1, 3);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 4, 1, 5);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 1, 3, 1);
INSERT INTO VENTES (NR, NP, NC, QT) VALUES (3, 1, 5, 1);
Écrire en SQL les requêtes permettant d'obtenir les informations suivantes.
Question
On souhaite les numéros des clients qui n'ont rien acheté à un représentant de Paris.
Indice
nc
----
1
2
4
5
Indice
SELECT C.NC
FROM CLIENTS C
WHERE 'Paris' NOT IN
(
...
) ;
Solution
SELECT C.NC
FROM CLIENTS C
WHERE 'Paris' NOT IN
(
SELECT R.VILLE
FROM VENTES V, REPRESENTANTS R
WHERE V.NR=R.NR
AND V.NC=C.NC
) ;
Solution alternative
SELECT C.NC
FROM CLIENTS C
WHERE NOT EXISTS (
SELECT R.*
FROM VENTES V, REPRESENTANTS R
WHERE V.NR=R.NR
AND V.NC=C.NC
AND R.VILLE='Paris'
) ;
Question
On souhaite les noms des représentants ayant vendu quelque chose aux clients 1 et 2.
Indice
nomr
----------
Stephane
Leonard
Indice
SELECT R.NOMR
FROM REPRESENTANTS R
WHERE 1 IN (...)
AND 2 IN (...);
Solution
SELECT R.NOMR
FROM REPRESENTANTS R
WHERE 1 IN (SELECT V.NC FROM VENTES V WHERE V.NR=R.NR)
AND 2 IN (SELECT V.NC FROM VENTES V WHERE V.NR=R.NR);
Question
Pour chaque couple de représentants ayant vendu dans la même ville, on souhaite le nom de la ville, le nom de ces représentants tel que celui a vendu le plus est en premier.
Proposez une solution avec vue, une solution avec sous-requête dans la clause FROM et une solution avec sous-requête dans la clause WHERE
Indice
ville | nomr | nomr
-----------+---------+----------
Compiègne | Antoine | Leonard
Compiègne | Antoine | Benjamin
Lyon | Leonard | Stephane
Solution
CREATE VIEW VR as SELECT R.NOMR, SUM(V.QT) total, C.VILLE
FROM REPRESENTANTS R, VENTES V, CLIENTS C
WHERE R.NR = V.NR
AND V.NC = C.NC
GROUP BY R.NOMR, C.VILLE ;
SELECT R1.VILLE, R1.NOMR, R2.NOMR
FROM VR R1, VR R2
WHERE R1.VILLE = R2.VILLE
AND R1.total > R2.total ;
SELECT R1.VILLE, R1.NOMR, R2.NOMR
FROM (
SELECT R.NOMR, SUM(V.QT) total, C.VILLE
FROM REPRESENTANTS R, VENTES V, CLIENTS C
WHERE R.NR = V.NR
AND V.NC = C.NC
GROUP BY R.NOMR, C.VILLE
) R1, (
SELECT R.NOMR, SUM(V.QT) total, C.VILLE
FROM REPRESENTANTS R, VENTES V, CLIENTS C
WHERE R.NR = V.NR
AND V.NC = C.NC
GROUP BY R.NOMR, C.VILLE
) R2
WHERE R1.VILLE = R2.VILLE
AND R1.total > R2.total ;
SELECT DISTINCT R1.NOMR, R2.NOMR, C1.VILLE
FROM REPRESENTANTS R1, REPRESENTANTS R2, CLIENTS C1
WHERE
(SELECT SUM(V.QT) FROM VENTES V, CLIENTS C WHERE V.NR = R1.NR AND V.NC = C.NC AND C.VILLE = C1.VILLE) >
(SELECT SUM(V.QT) FROM VENTES V, CLIENTS C WHERE V.NR = R2.NR AND V.NC = C.NC AND C.VILLE = C1.VILLE) ;
Question
On souhaite les noms des représentants ayant vendu quelque chose à tous les clients.
On proposera une solution avec une vue et au moins une solution avec des sous-requêtes.
Indice
nomr
---------
Leonard
Solution
Avec une vue
CREATE VIEW vue AS
SELECT R.NOMR, C.NC
FROM REPRESENTANTS R, CLIENTS C
EXCEPT
SELECT R.NOMR, V.NC
FROM REPRESENTANTS R, VENTES V
WHERE V.NR=R.NR;
SELECT R.NOMR
FROM REPRESENTANTS R, VENTES V
WHERE R.NR=V.NR
EXCEPT
SELECT NOMR FROM vue;
Sans vue
SELECT R.NOMR
FROM REPRESENTANTS R
WHERE R.NR IN (
SELECT V.NR
FROM VENTES V
GROUP BY V.NR
HAVING COUNT(DISTINCT V.NC) = (SELECT COUNT (*) FROM CLIENTS)) ;
SELECT R.NOMR
FROM REPRESENTANTS R
WHERE
(SELECT COUNT(DISTINCT V.NC) FROM VENTES V WHERE V.NR=R.NR)
=
(SELECT COUNT (*) FROM CLIENTS) ;
SELECT R.NOMR
FROM REPRESENTANTS R
WHERE NOT EXISTS (
SELECT C.*
FROM CLIENTS C
WHERE NOT EXISTS (
SELECT V.*
FROM VENTES V
WHERE C.NC=V.NC AND V.NR=R.NR)
) ;