|
|
-- 1. Nombre de violons loués par des élèves.
|
|
|
SELECT COUNT(*) FROM louer WHERE instrument = (
|
|
|
SELECT id FROM instrument WHERE designation = 'Violon'
|
|
|
);
|
|
|
|
|
|
-- 2. Numéros, noms et prénoms des élèves louant plus de 2 instruments.
|
|
|
SELECT e.num, e.nom, e.prenom
|
|
|
FROM louer l
|
|
|
INNER JOIN eleve e ON e.num = l.eleve
|
|
|
GROUP BY e.num
|
|
|
HAVING COUNT(*) > 1;
|
|
|
|
|
|
-- 3. Pour chaque instrument (id, designation), plus vieil élève (nom, prénom) suivant un cours de cet instrument.
|
|
|
WITH plusVieuxEleves AS (
|
|
|
SELECT MAX(e.age) age, s.instrument FROM suivre s
|
|
|
INNER JOIN eleve e ON e.num = s.eleve
|
|
|
GROUP BY s.instrument
|
|
|
)
|
|
|
SELECT i.id, i.designation, e.nom, e.prenom FROM suivre s
|
|
|
INNER JOIN instrument i ON i.id = s.instrument
|
|
|
INNER JOIN eleve e ON e.num = s.eleve
|
|
|
INNER JOIN plusVieuxEleves p ON p.age = e.age AND s.instrument = s.instrument;
|
|
|
|
|
|
-- 4. Définir la fonction PL/pgSQL total qui prend en paramètre un numéro d’élève et retourne le montant total qu’il doit régler à l’école de musique (pour les cours et la location des instruments) sachant qu’une inscription à un cours correspond à 30h de cours par an
|
|
|
CREATE OR REPLACE FUNCTION total(eleve_num INT)
|
|
|
RETURNS INT AS $$
|
|
|
DECLARE
|
|
|
totalCours INT;
|
|
|
totalInstruments INT;
|
|
|
BEGIN
|
|
|
SELECT COALESCE(SUM(n.tarifHoraire * 30), 0) INTO STRICT totalCours FROM suivre s
|
|
|
INNER JOIN niveau n ON n.niveau = s.niveau
|
|
|
WHERE s.eleve = eleve_num;
|
|
|
|
|
|
SELECT COALESCE(SUM(i.tarifLocation), 0) INTO STRICT totalInstruments FROM louer l
|
|
|
INNER JOIN instrument i ON i.id = l.instrument
|
|
|
WHERE l.eleve = eleve_num;
|
|
|
|
|
|
RETURN totalCours + totalInstruments;
|
|
|
END;
|
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
-- 5. Utiliser la fonction total pour afficher le montant dû par chaque élève (num, nom, prénom)
|
|
|
SELECT num, nom, prenom, total(num) FROM eleve;
|
|
|
|
|
|
-- 6. Mettre à jour le tarif de location des instruments loués plus de 10 fois, en augmentant leur tarif de 50€.
|
|
|
-- Un GROUP BY ne s'associe pas vraiment avec un update :/
|
|
|
/*UPDATE instrument i SET tarifLocation = tarifLocation + 50
|
|
|
FROM louer l
|
|
|
WHERE l.instrument = i.id
|
|
|
GROUP BY i.id
|
|
|
HAVING COUNT(*) > 10;*/
|
|
|
UPDATE instrument SET tarifLocation = tarifLocation + 50
|
|
|
WHERE id IN (
|
|
|
SELECT instrument FROM louer
|
|
|
GROUP BY instrument
|
|
|
HAVING COUNT(*) > 10
|
|
|
);
|
|
|
|
|
|
/*DO $$
|
|
|
DECLARE
|
|
|
curs cursor FOR SELECT i.id FROM louer l
|
|
|
INNER JOIN instrument i ON l.instrument = i.id
|
|
|
GROUP BY i.id
|
|
|
HAVING COUNT(*) > 10
|
|
|
FOR UPDATE;
|
|
|
instrument_courant INT;
|
|
|
BEGIN
|
|
|
open curs;
|
|
|
fetch curs into instrument_courant;
|
|
|
while found loop
|
|
|
UPDATE instrument SET tarifLocation = tarifLocation + 50 WHERE CURRENT OF curs;
|
|
|
fetch curs into instrument_courant;
|
|
|
end loop;
|
|
|
close curs;
|
|
|
END;
|
|
|
$$ LANGUAGE plpgsql;*/
|
|
|
DO $$
|
|
|
DECLARE
|
|
|
curs cursor FOR SELECT instrument FROM louer
|
|
|
GROUP BY instrument
|
|
|
HAVING COUNT(*) > 10;
|
|
|
instrument_courant INT;
|
|
|
BEGIN
|
|
|
open curs;
|
|
|
fetch curs into instrument_courant;
|
|
|
while found loop
|
|
|
UPDATE instrument SET tarifLocation = tarifLocation + 50 WHERE instrument = instrument_courant;
|
|
|
fetch curs into instrument_courant;
|
|
|
end loop;
|
|
|
close curs;
|
|
|
END;
|
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
|
|
-- 7. Créer une vue ElevesPiano rassemblant toutes les informations sur les élèves (nom, prénom, âge, adresse et niveau) des élèves qui suivent des cours de piano
|
|
|
CREATE VIEW ElevesPiano AS
|
|
|
SELECT e.nom, e.prenom, e.age, e.rue || e.codePostal || e.ville adresse, s.niveau
|
|
|
FROM suivre s
|
|
|
INNER JOIN eleve e ON e.num = s.eleve
|
|
|
WHERE s.instrument = (SELECT id FROM instrument WHERE designation = 'Piano');
|
|
|
|
|
|
-- 8. Créer un utilisateur rh pouvant créer des rôles.
|
|
|
CREATE USER rh CREATEROLE;
|
|
|
|
|
|
-- 9. Donner à l’utilisateur rh l’autorisation de consulter, ajouter, supprimer et modifier des lignes de la table Professeur.
|
|
|
GRANT CONNECT ON DATABASE dbclfreville2 TO rh;
|
|
|
GRANT SELECT, INSERT, DELETE, UPDATE ON Professeur TO rh;
|
|
|
|
|
|
-- 10. L’administrateur de la base de données décide de changer de fonctionnement : au lieu d’avoir un seul compte rh utilisé par tous les RH de l’école de musique, il veut créer un compte pour chacun d’entre eux, mais qu’ils aient tous les droits de rh. (Le rôle rh ne devra plus être utilisable directement.)
|
|
|
--REVOKE LOGIN TO rh; -- Instruction seulement pour une base de données précise
|
|
|
ALTER ROLE rh RESET LOGIN;
|
|
|
CREATE USER ldupond PASSWORD 'azerty';
|
|
|
GRANT rh TO ldupond;
|
|
|
|
|
|
-- *quelques expérimentations sur la performance de ces requêtes*
|
|
|
EXPLAIN ANALYZE SELECT id FROM restaurant WHERE min_price >= ALL (SELECT min_price FROM restaurant); -- 178 / 21
|
|
|
EXPLAIN ANALYZE SELECT id FROM restaurant ORDER BY min_price DESC LIMIT 1; -- 5
|
|
|
EXPLAIN ANALYZE SELECT id FROM restaurant ORDER BY min_price DESC FETCH FIRST 1 ROWS ONLY; -- 5
|
|
|
EXPLAIN ANALYZE SELECT id FROM restaurant WHERE min_price = (SELECT MAX(min_price) FROM restaurant); -- 6
|
|
|
|
|
|
/*for cle, valeur in dictionnaire:
|
|
|
if valeur >= local_max:
|
|
|
local_max = valeur
|
|
|
local_max_cle = cle*/
|
|
|
|