-- 2. Ecrire un bloc PL/pgSQL anonyme qui affiche

DO $$
    DECLARE
        a numeric := 0;
        b numeric := 1;
        c numeric;
        i integer := 0;
    BEGIN
        WHILE i<10 LOOP
            c=a+b;
            RAISE NOTICE 'a=% b=% c=%', a, b, c;
            a=b;
            b=c;
            i=i+1;
        END LOOP;
    END;
$$;

-- 3. Faire la meme mais en fonction pgSQL

CREATE OR REPLACE FUNCTION fibonacci(n integer) RETURNS SETOF integer AS $$
    DECLARE
        a numeric := 0;
        b numeric := 1;
        c numeric;
        i integer := 0;
    BEGIN
        WHILE i<(n-1) LOOP
            c=a+b;
            -- RAISE NOTICE 'a=% b=% c=%', a, b, c;
            a=b;
            b=c;
            i=i+1;
            RETURN NEXT c;
        END LOOP;
    END;
$$ LANGUAGE plpgsql;

-- 4. Appel de la fonction avec comme parametre 0, 1, 2, 10

SELECT fibonacci(0);
SELECT * FROM fibonacci(1);
SELECT * FROM fibonacci(2);
SELECT * FROM fibonacci(10);

-- fibonacci 
-- -----------
-- (0 ligne)

--  fibonacci 
-- -----------
-- (0 ligne)

--  fibonacci 
-- -----------
--          1
-- (1 ligne)

--  fibonacci 
-- -----------
--          1
--          2
--          3
--          5
--          8
--         13
--         21
--         34
--         55
-- (9 lignes)



-- 5. Ecrire une fonction en plpgsql nb_athletes qui retourn le nombre d'athlètes d'un pays dont le code est passé en paramètre

CREATE OR REPLACE FUNCTION nb_athletes(pays_code character varying) RETURNS integer AS $$
    DECLARE
        nb_athletes integer;
    BEGIN
        SELECT COUNT(*) INTO nb_athletes FROM athlete WHERE pays = pays_code;
        RETURN nb_athletes;
    END;
$$ LANGUAGE plpgsql;

-- 6. Utiliser la fonction précédente pour calculer le nombre d'athlèthes français

SELECT nb_athletes('FRA');

-- nb_athletes 
-- -------------
--          396
-- (1 ligne)


-- 7. Ecrire une requete sql utilisant la fonction nb_athletes pour afficher le code et le nom de tous les pays ayant plus d'athlètes que la France

SELECT pays, nom FROM pays WHERE nb_athletes(pays.code) > nb_athletes('FRA');

-- pays                |            nom             
-- ------------------------------------+----------------------------
--  (AUS,Australia)                    | Australia
--  (USA,"United States of America")   | United States of America
--  (GER,Germany)                      | Germany
--  (JPN,Japan)                        | Japan
--  (CHN,"People's Republic of China") | People's Republic of China
-- (5 lignes)

-- 8. Ecrire une fonction en pgpsql epr qui prend deux paramètres (le nom d'une discipline et une date) et qui retourne les epreuves (code et nom) de cette discipline ayant lieu à la date donnée

CREATE OR REPLACE FUNCTION epr(discipline varchar, date date) RETURNS SETOF epreuve AS $$
    DECLARE
        epreuve epreuve;
    BEGIN
        FOR epreuve IN SELECT * 
                        FROM epreuve e, discipline d
                        WHERE e.discipl = d.code AND e.dateE = date LOOP
            RETURN NEXT epreuve;
        END LOOP;
    END;
$$ LANGUAGE plpgsql;

-- %TYPE pour recuperer le type de la colonne

-- 9. Utiliser la fonction epr pour afficher les noms des epreuves d'athlètisme ('Athletics') ayant lieu le 3 août 2021

SELECT epr('Athletics', '2021-08-03');

-- epr                                  
-- ----------------------------------------------------------------------
--  (E206,GAR,"Men's Horizontal Bar",2021-08-03)
--  (E207,GAR,"Men's Parallel Bars",2021-08-03)
--  (E208,GAR,"Women's Balance Beam",2021-08-03)
--  (E209,ATH,"Men's 400m Hurdles",2021-08-03)
--  (E210,ATH,"Men's Pole Vault",2021-08-03)
--  (E211,ATH,"Women's 200m",2021-08-03)
--  (E212,ATH,"Women's 800m",2021-08-03)
--  (E213,ATH,"Women's Hammer Throw",2021-08-03)
--  (E214,ATH,"Women's Long Jump",2021-08-03)
--  (E215,BOX,"Men's Feather (52-57kg)",2021-08-03)
--  (E216,BOX,"Men's Heavy (81-91kg)",2021-08-03)
--  (E217,BOX,"Men's Welter (63-69kg)",2021-08-03)
--  (E218,BOX,"Women's Feather (54-57kg)",2021-08-03)
--  (E219,CSP,"Men's Canoe Double 1000m",2021-08-03)
--  (E220,CSP,"Men's Kayak Single 1000m",2021-08-03)
--  (E221,CSP,"Women's Kayak Double 500m",2021-08-03)
--  (E222,CSP,"Women's Kayak Single 200m",2021-08-03)
--  (E223,CTR,"Men's Team Sprint",2021-08-03)
--  (E224,CTR,"Women's Team Pursuit",2021-08-03)
--  (E225,DIV,"Men's 3m Springboard",2021-08-03)
--  (E226,SAL,"Men's One Person Dinghy (Heavyweight) - Finn",2021-08-03)
--  (E227,SAL,"Men's Skiff - 49er",2021-08-03)
--  (E228,SAL,"Mixed Multihull - Nacra 17 Foiling",2021-08-03)
--  (E229,SAL,"Women's Skiff - 49er FX",2021-08-03)
--  (E230,WLF,"Men's 109kg",2021-08-03)
--  (E231,WRE,"Men's Greco-Roman 77kg",2021-08-03)
--  (E232,WRE,"Men's Greco-Roman 97kg",2021-08-03)
--  (E233,WRE,"Women's Freestyle 68kg",2021-08-03)
-- (28 lignes)

-- 10. Le mauvais temps empêche la tenue de compétition en exterieur. Utiliser la fonction epr pour décaler d'un jour toutes les epreuves d'équitation ('Equestrian') ayant lieu le 2 août 2021

SELECT epr('Equestrian', '2021-08-02');

-- epr                        
-- ---------------------------------------------------
--  (E186,GAR,"Men's Rings",2021-08-02)
--  (E187,GAR,"Men's Vault",2021-08-02)
--  (E188,GAR,"Women's Floor Exercise",2021-08-02)
--  (E189,ATH,"Men's 3000m Steeplechase",2021-08-02)
--  (E190,ATH,"Men's Long Jump",2021-08-02)
--  (E191,ATH,"Women's 100m Hurdles",2021-08-02)
--  (E192,ATH,"Women's 5000m",2021-08-02)
--  (E193,ATH,"Women's Discus Throw",2021-08-02)
--  (E194,BDM,"Men's Singles",2021-08-02)
--  (E195,BDM,"Women's Doubles",2021-08-02)
--  (E196,CTR,"Women's Team Sprint",2021-08-02)
--  (E197,EQU,"Eventing Individual",2021-08-02)
--  (E198,EQU,"Eventing Team",2021-08-02)
--  (E199,SHO,"25m Rapid Fire Pistol Men",2021-08-02)
--  (E200,SHO,"50m Rifle 3 Positions Men",2021-08-02)
--  (E201,WLF,"Women's +87kg",2021-08-02)
--  (E202,WLF,"Women's 87kg",2021-08-02)
--  (E203,WRE,"Men's Greco-Roman 130kg",2021-08-02)
--  (E204,WRE,"Men's Greco-Roman 60kg",2021-08-02)
--  (E205,WRE,"Women's Freestyle 76kg",2021-08-02)
-- (20 lignes)

-- UPDATE 0

-- 11. Ecrire une fonction pratique qui retourne le nom de la discipline pratiqué par un athlète dont on passe le code en paramètre

CREATE OR REPLACE FUNCTION pratique(code_athlete athlete.code%TYPE) RETURNS SETOF discipline AS $$
    DECLARE
        discipline discipline;
    BEGIN
        FOR discipline IN SELECT * FROM discipline d WHERE d.code IN (SELECT p.discipl FROM pratiquer p WHERE p.athlete = (SELECT a.code FROM athlete a WHERE a.nom = nom AND a.prenom = prenom)) LOOP
            RETURN NEXT discipline;
        END LOOP;
    EXCEPTION
        WHEN UNIQUE_VIOLATION THEN
            RAISE NOTICE 'L ''athlète % pratique plusieurs disciplines', code_athlete;
        WHEN NO_DATA_FOUND THEN
            RAISE NOTICE 'Athlète % inconnu', code_athlete;
    END;
$$ LANGUAGE plpgsql;

-- CREATE OR REPLACE FUNCTION pratique(code_athlete varchar) RETURNS SETOF discipline AS $$
--     SELECT * 
--     FROM discipline d 
--     WHERE d.code IN (SELECT discipl FROM pratiquer WHERE athlete = code_athlete);
--     EXEPTION
--         WHEN UNIQUE_VIOLATION THEN
--             RAISE NOTICE 'L ''athlète % pratique plusieurs disciplines', code_athlete;
--         WHEN NO_DATA_FOUND THEN
--             RAISE NOTICE 'Athlète % inconnu', code_athlete;
-- $$ LANGUAGE SQL;

-- 12. Utiliser la fonction pratique pour trouver le sport pratiqué par Earvin NGAPETH

SELECT code 
FROM athlete 
WHERE nom = 'NGAPETH' AND prenom = 'Earvin';

SELECT * FROM pratique('A07318');

-- code |    nom     
-- ------+------------
--  VVO  | Volleyball
-- (1 ligne)

-- 13. Meme question pour l'athlete Lotte KOPECKY

SELECT code
FROM athlete
WHERE nom = 'KOPECKY' AND prenom = 'Lotte';

SELECT * FROM pratique('A05315');

-- code |      nom      
-- ------+---------------
--  CRD  | Cycling Road
--  CTR  | Cycling Track
-- (2 lignes)

-- 14. Meme question pour l'thlete de code 'B01' (qui n'existe pas)

SELECT * FROM pratique('B01');



