\! clear -- -- -- ? 1 - Écrire une fonction qui pour un match donné calcule le nombre de rebonds -- -- -- ? pris par les joueurs qui n’ont pas débuté la rencontre. Proposez deux versions, -- -- -- ? une utilisant les fonctions d’agrégation et une autre utilisant un curseur mais aucune fonction d’agrégation. -- -- CREATE OR REPLACE FUNCTION calcul_rebonds(match Game.id%TYPE) RETURNS integer AS $$ -- -- DECLARE -- -- sumRebounds integer; -- -- BEGIN -- -- SELECT sum(gd.rebounds) INTO sumRebounds -- -- FROM GameDetail gd, Game g -- -- WHERE g.id = match AND gd.idGame = g.id AND gd.startPosition is NULL; -- -- RETURN sumRebounds; -- -- END; -- -- $$ LANGUAGE plpgsql; -- -- SELECT calcul_rebonds('22100979'); -- -- -- CREATE FUNCTION -- -- -- calcul_rebonds -- -- -- ---------------- -- -- -- 32 -- -- -- (1 row) -- -- CREATE OR REPLACE FUNCTION calcul_rebonds_curs(match Game.id%TYPE) RETURNS GameDetail.rebounds%TYPE AS $$ -- -- DECLARE -- -- sumRebounds GameDetail.rebounds%TYPE := 0; -- -- rbs GameDetail.rebounds%TYPE := 0; -- -- curs cursor FOR SELECT rebounds -- -- FROM GameDetail -- -- WHERE idGame = match AND startPosition is NULL AND rebounds is NOT NULL; -- -- BEGIN -- -- OPEN curs; -- -- FETCH curs INTO rbs; -- -- WHILE FOUND LOOP -- -- sumRebounds = sumRebounds + rbs; -- -- FETCH curs INTO rbs; -- -- END LOOP; -- -- CLOSE curs; -- -- RETURN sumRebounds; -- -- END; -- -- $$ LANGUAGE plpgsql; -- -- SELECT calcul_rebonds_curs('22100979'); -- -- -- CREATE FUNCTION -- -- -- calcul_rebonds_curs -- -- -- --------------------- -- -- -- 32 -- -- -- (1 row) -- -- -- ? 2 - Vérifier que vos deux versions retournent les mêmes résultats en affichant le nombre total de rebonds -- -- -- ? pris par les joueurs n’ayant pas débuté la rencontre pour tous les matchs ayant eu lieu le 12 mars 2022. -- -- SELECT calcul_rebonds(id) -- -- FROM Game -- -- WHERE dateGame = '2022-03-12'; -- -- -- calcul_rebonds -- -- -- ---------------- -- -- -- 39 -- -- -- 20 -- -- -- 43 -- -- -- 40 -- -- -- 41 -- -- -- 25 -- -- -- 24 -- -- -- (7 rows) -- -- SELECT calcul_rebonds_curs(id) -- -- FROM Game -- -- WHERE dateGame = '2022-03-12'; -- -- -- calcul_rebonds_curs -- -- -- --------------------- -- -- -- 39 -- -- -- 20 -- -- -- 43 -- -- -- 40 -- -- -- 41 -- -- -- 25 -- -- -- 24 -- -- -- (7 rows) -- -- -- ? 3 - Écrire une fonction qui calcule la même chose mais pour les joueurs ayant débuté la rencontre, -- -- -- ? autrement dit qui calcule, pour un match donné, le nombre de rebonds pris par les joueurs ayant débuté la rencontre. -- -- CREATE OR REPLACE FUNCTION calcul_rebonds_t(match Game.id%TYPE) RETURNS integer AS $$ -- -- DECLARE -- -- sumRebounds integer; -- -- BEGIN -- -- SELECT sum(gd.rebounds) INTO sumRebounds -- -- FROM GameDetail gd, Game g -- -- WHERE g.id = match AND gd.idGame = g.id AND gd.startPosition is NOT NULL; -- -- IF sumRebounds is NULL THEN -- -- RETURN 0; -- -- END IF; -- -- RETURN sumRebounds; -- -- END; -- -- $$ LANGUAGE plpgsql; -- -- SELECT calcul_rebonds_t('22100979'); -- -- -- CREATE FUNCTION -- -- -- calcul_rebonds_t -- -- -- ------------------ -- -- -- 57 -- -- -- (1 row) -- -- CREATE OR REPLACE FUNCTION calcul_rebonds_curs_t(match Game.id%TYPE) RETURNS GameDetail.rebounds%TYPE AS $$ -- -- DECLARE -- -- sumRebounds GameDetail.rebounds%TYPE := 0; -- -- rbs GameDetail.rebounds%TYPE := 0; -- -- curs cursor FOR SELECT rebounds -- -- FROM GameDetail -- -- WHERE idGame = match AND startPosition is NOT NULL AND rebounds is NOT NULL; -- -- BEGIN -- -- OPEN curs; -- -- FETCH curs INTO rbs; -- -- WHILE FOUND LOOP -- -- sumRebounds = sumRebounds + rbs; -- -- FETCH curs INTO rbs; -- -- END LOOP; -- -- CLOSE curs; -- -- RETURN sumRebounds; -- -- END; -- -- $$ LANGUAGE plpgsql; -- -- SELECT calcul_rebonds_curs_t('22100979'); -- -- -- CREATE FUNCTION -- -- -- calcul_rebonds_curs_t -- -- -- ----------------------- -- -- -- 57 -- -- -- (1 row) -- -- SELECT calcul_rebonds_t('10300004'); -- -- SELECT calcul_rebonds_curs_t('10300004'); -- -- -- ? 4 - Trouver le match (abréviation des équipes et date) pendant lequel les joueurs -- -- -- ? ayant débuté la rencontre ont réalisé le plus de rebonds. -- -- SELECT t1.abbreviation, t2.abbreviation, g.dateGame, calcul_rebonds_t(g.id) -- -- FROM Game g, Team t1, Team t2 -- -- WHERE g.idHomeTeam = t1.id AND g.idVisitorTeam = t2.id AND calcul_rebonds_t(g.id) = (SELECT max(calcul_rebonds_t(id)) -- -- FROM Game); -- -- -- abbreviation | abbreviation | dategame | calcul_rebonds_t -- -- -- --------------+--------------+------------+------------------ -- -- -- POR | DEN | 2019-05-03 | 101 -- -- -- (1 row) -- -- -- ? 5 - Y a t’il des matchs pour lesquels les données sur les rebonds sont incohérentes? -- -- -- ? Vérifier en comparant les valeurs obtenus grâce aux fonctions précédentes avec les valeurs contenues dans la table Game. -- -- -- ! SELECT t1.abbreviation, t2.abbreviation, g.dateGame, (calcul_rebonds_t(g.id) + calcul_rebonds(g.id)) as fct, g.reboundsHome, g.reboundsAway -- -- -- ! FROM Game g, Team t1, Team t2 -- -- -- ! WHERE g.idHomeTeam = t1.id AND g.idVisitorTeam = t2.id AND calcul_rebonds_t(g.id) = (SELECT max(calcul_rebonds_t(id)) -- -- -- ! FROM Game); -- -- -- ? 6 - Écrire une fonction qui pour un match et une équipe donnée calcule le total des points des joueurs de cet équipe pendant le match, -- -- -- ? à partir des données contenues dans la table GameDetail. -- -- CREATE OR REPLACE FUNCTION PtsTotJoueur(match Game.id%TYPE, team Team.id%TYPE) -- -- RETURNS integer as $$ -- -- DECLARE total integer; -- -- BEGIN -- -- SELECT sum(points) INTO total -- -- FROM GameDetail -- -- WHERE idTeam = team AND idGame = match AND points IS NOT NULL; -- -- IF total is NULL THEN -- -- RETURN 0; -- -- END IF; -- -- RETURN total; -- -- END; -- -- $$ LANGUAGE plpgsql; -- -- SELECT PtsTotJoueur('22101006','1610612741'); -- -- -- ? 7 - Utiliser cette fonction pour vérifier si les valeurs ptsHome et ptsAway de la table Game sont correctes. -- -- SELECT g.id AS idGame, t.id AS idTeam, g.ptsHome, g.ptsAway, PtsTotJoueur(g.id, g.idHomeTeam) AS ptsHome1, PtsTotJoueur(g.id, g.idVisitorTeam) AS ptsAway2 -- -- FROM GAME g, Team t -- -- WHERE g.idVisitorTeam = t.id; -- -- -- ? 8 - Quelle table contient des données incorrectes/incomplètes ? Game ou GameDetail ? Vérifier grâce aux résultats officiels des matchs. -- -- ? 9 - Ecrire une fonction isBestAtHome qui retourne un booléen indiquant si une équipe donnée a -- -- ? gagné au moins autant de matchs à domicile qu’à l’extérieur lors de la saison passée en paramètre. -- CREATE OR REPLACE FUNCTION isBestAtHome(IdTeam Team.id%TYPE, GameSeason Game.season%TYPE) RETURNS numeric AS $$ -- DECLARE -- home_wins integer; -- away_wins integer; -- BEGIN -- SELECT COUNT(*) INTO home_wins -- FROM GAME g -- WHERE g.season = GameSeason AND g.idHomeTeam = IdTeam AND g.ptsHome > g.ptsAway; -- SELECT COUNT(*) INTO away_wins -- FROM GAME g -- WHERE g.season = GameSeason AND g.idVisitorTeam = IdTeam AND g.ptsAway > g.ptsHome; -- IF (home_wins >= away_wins) THEN -- RETURN 1; -- ELSE -- RETURN 0; -- END IF; -- END; -- $$ LANGUAGE plpgsql; -- -- ? 10 - Vérifier que l’équipe des Spurs a été meilleure à domicile qu’à l’extérieur pendant la saison 2021. -- SELECT isBestAtHome(id, '2021') AS best_at_home -- FROM Team -- WHERE abbreviation = 'SAS'; -- -- ? 11 - Ecrire une fonction bestAtHome qui retourne une table avec les équipes (ids, abbréviations, noms et villes) -- -- ? qui ont gagné au moins autant de matchs à domicile qu’à l’extérieur lors de la saison passée en paramètre. -- CREATE OR REPLACE FUNCTION BestAtHome(GameSeason Game.season%TYPE) -- RETURNS TABLE(id Team.id%TYPE, abbreviation Team.abbreviation%TYPE, nom Team.nickname%TYPE, ville Team.city%TYPE) AS $$ -- BEGIN -- RETURN QUERY SELECT DISTINCT t.id, t.abbreviation, t.nickname, t.city -- FROM Team t -- WHERE isBestAtHome(t.id, GameSeason) = 1; -- END; -- $$ LANGUAGE plpgsql; -- -- ? 12 - Quelles équipes ont gagné au moins autant de matchs à domicile qu’à l’extérieur en 2021? -- SELECT BestAtHome(2021); -- -- ? 13 - Ecrire une fonction qui retourne un booléen indiquant si une équipe donnée à gagner au moins autant de matchs à -- -- ? domiciles qu’à l’extérieur pendant au moins n saisons consécutives, où n est un paramètre de la fonction. -- -- ? Cette fonction devra lever une exception personnalisée si n n’est pas une valeur possible. -- CREATE OR REPLACE FUNCTION isBestAtHomeDuring(teamID Team.id%TYPE, n integer) RETURNS integer AS $$ -- DECLARE -- home_wins integer; -- away_wins integer; -- consecutive_seasons integer; -- BEGIN -- -- Vérifier que n est une valeur valide (n doit être supérieur ou égal à 1) -- IF n < 1 THEN -- RAISE EXCEPTION 'La valeur de n doit être d''au moins 1.'; -- END IF; -- -- Compter le nombre de saisons -- SELECT COUNT(DISTINCT season) INTO consecutive_seasons -- FROM Game -- WHERE idHomeTeam = teamID OR idVisitorTeam = teamID; -- -- Vérifier si l'équipe a gagné au moins autant de matchs à domicile qu'à l'extérieur pour n saisons consécutives -- FOR i IN 1..consecutive_seasons - n + 1 LOOP -- SELECT COUNT(*) INTO home_wins -- FROM Game -- WHERE season BETWEEN i AND i + n - 1 -- AND idHomeTeam = teamID -- AND ptsHome > ptsAway; -- SELECT COUNT(*) INTO away_wins -- FROM Game -- WHERE season BETWEEN i AND i + n - 1 -- AND idVisitorTeam = teamID -- AND ptsAway > ptsHome; -- IF home_wins >= away_wins THEN -- RETURN 1; -- END IF; -- END LOOP; -- RETURN 0; -- END; -- $$ LANGUAGE plpgsql; -- SELECT isBestAtHomeDuring('1610612737', 1) AS best_at_home_during_one_seasons; -- -- ? 14 - Y a t’il des équipes qui ont gagné au moins autant de matchs à domicile qu’à l’extérieur -- -- ? pendant 2 saisons consécutives ? Pendant 3 saisons consécutives ? -- SELECT isBestAtHomeDuring('1610612737', 2) AS best_at_home_during_two_seasons; -- SELECT isBestAtHomeDuring('1610612737', 3) AS best_at_home_during_three_seasons; -- -- ? 15 - Écrire une fonction qui calcule l’id de l’équipe ayant le meilleur pourcentage moyen de paniers -- -- ? à 3 points d’une saison donnée. -- CREATE OR REPLACE FUNCTION idTeam3Points(GameSeason numeric) RETURNS character varying AS $$ -- DECLARE -- bestTeamID character varying; -- BEGIN -- SELECT INTO bestTeamID gd.idTeam -- FROM GameDetail gd, Game g -- WHERE gd.idGame = g.id AND g.season = GameSeason -- GROUP BY gd.idTeam -- ORDER BY AVG(gd.threePointsPrctage) DESC -- LIMIT 1; -- RETURN bestTeamID; -- END; -- $$ LANGUAGE plpgsql; -- -- ? 16 - Utiliser cette fonction pour afficher la meilleure équipe (abbréviation, nom et ville) de la saison 2021 en pourcentage moyen de paniers à 3 points -- SELECT abbreviation, nickname, city -- FROM Team -- WHERE id = idTeam3Points('2021'); -- -- ! charge infiniment -- -- ? 17 - Écrire une fonction qui calcule combien de paniers à trois points ont été marqué par un joueur donné, pendant une saison donnée. -- CREATE OR REPLACE FUNCTION count3pointsbyplayer(idP character varying, GameSeason numeric) RETURNS numeric AS $$ -- DECLARE -- totalThreePoints numeric; -- BEGIN -- SELECT SUM(gd.threePointsMade) -- INTO totalThreePoints -- FROM GameDetail gd -- JOIN Game g ON gd.idGame = g.id -- WHERE gd.idPlayer = idP AND g.season = GameSeason; -- RETURN totalThreePoints; -- END; -- $$ LANGUAGE plpgsql; -- SELECT count3pointsbyplayer('203932', '2021'); -- -- ? 18 - Écrire une fonction qui calcule l’id du joueur ayant marqué le plus de paniers à trois points pendant une saison donnée. -- CREATE OR REPLACE FUNCTION idPlayerMost3Points(GameSeason Game.season%TYPE) RETURNS Player.id%TYPE AS $$ -- DECLARE -- best_player_id Player.id%TYPE; -- BEGIN -- SELECT gd.idPlayer INTO best_player_id -- FROM GameDetail gd -- JOIN Game g ON gd.idGame = g.id -- WHERE g.season = GameSeason -- GROUP BY gd.idPlayer -- ORDER BY SUM(gd.threePointsMade) DESC -- LIMIT 1; -- RETURN best_player_id; -- END; -- $$ LANGUAGE plpgsql; -- SELECT idPlayerMost3Points('2021'); -- -- ? 19 - En utilisant les fonctions précédement créées, écrire un bloc anonyme qui affiche pour chaque saison, par ordre chronologique, -- -- ? le nom du joueur ayant marqué le plus de paniers à trois points ainsi que le nombres de paniers à trois points marqués. -- DO $$ -- DECLARE -- season_value Game.season%TYPE; -- player_id Player.id%TYPE; -- total_3_points numeric; -- BEGIN -- FOR season_value IN (SELECT DISTINCT season FROM Game ORDER BY season) LOOP -- player_id := idPlayerMost3Points(season_value); -- total_3_points := count3PointsByPlayer(player_id, season_value); -- RAISE NOTICE 'Saison %: Joueur ID %, Nombre de paniers à trois points : %', season_value, player_id, total_3_points; -- END LOOP; -- END; -- $$; -- -- ? 20 - Ce calcul est très long. Pour effectuer un calcul plus efficace, nous allons créer une table supplémentaire permettant de stocker des statistiques. -- -- ? Créer la table Stats(season, player, threePoints) contenant le nombre de paniers à trois points marqués par chaque joueur pendant une saison et -- -- ? la remplir avec les données contenues dans GameDetail. -- -- ? △! Penser à éliminer les valeurs NULL. -- CREATE TABLE Stats ( -- season numeric, -- player varchar(10), -- threePoints numeric -- ); -- -- Insertion des données de GameDetail dans la table Stats -- INSERT INTO Stats (season, player, threePoints) -- SELECT g.season, gd.idPlayer, SUM(gd.threePointsMade) -- FROM GameDetail gd, Game g -- WHERE gd.idGame = g.id AND gd.threePointsMade IS NOT NULL -- GROUP BY g.season, gd.idPlayer; -- ? 21 - Utiliser la table Stats pour refaire le calcul de la question 19. SELECT s.season, s.player, s.threePoints FROM Stats s WHERE s.threePoints >= ALL(SELECT threePoints FROM Stats s2 WHERE s2.season = s.season); -- ? 22 - Écrire une fonction qui calcule la différence #rebonds offensifs - #rebonds défensifs -- ? pour un joueur et une saison donnée. -- ! △! aux valeurs nulles ! CREATE OR REPLACE FUNCTION reboundsDifference(idP Player.id%TYPE, GameSeason Game.season%TYPE) RETURNS integer AS $$ DECLARE offensiveRebounds integer; defensiveRebounds integer; BEGIN SELECT SUM(gd.offensiveRebounds) INTO offensiveRebounds FROM GameDetail gd, Game g WHERE gd.idGame = g.id AND gd.idPlayer = idP AND g.season = GameSeason; SELECT SUM(gd.defensiveRebounds) INTO defensiveRebounds FROM GameDetail gd, Game g WHERE gd.idGame = g.id AND gd.idPlayer = idP AND g.season = GameSeason; RETURN offensiveRebounds - defensiveRebounds; END; $$ LANGUAGE plpgsql; SELECT reboundsDifference('203932', '2021'); -- CREATE FUNCTION -- reboundsdifference -- -------------------- -- -165 -- (1 row) -- ? 23 - Ajouter une colonne reboundsRatio à la table Stats. ALTER TABLE Stats ADD reboundsRatio integer; -- ? 24 - Écrire un bloc anonyme permettant de remplir la colonne reboundsRatio. DO $$ DECLARE SaisonS Game.season%TYPE; PlayerId Player.id%TYPE; rebondsDifference integer; BEGIN FOR SaisonS IN (SELECT DISTINCT season FROM Game ORDER BY season) LOOP FOR PlayerId IN (SELECT DISTINCT p.id FROM Player p, Game g, GameDetail gd WHERE p.id = gd.idPlayer AND g.id = gd.idGame AND g.season = SaisonS) LOOP rebondsDifference := reboundsDifference(PlayerId, SaisonS); UPDATE Stats SET reboundsRatio = rebondsDifference WHERE season = SaisonS AND player = PlayerId; END LOOP; END LOOP; END; $$; -- ? 25 - Afficher (sur une seule ligne) le joueur ayant réalisé pendant une saison le plus grand et celui -- ? ayant réalisé le plus petit ratio de rebonds. SELECT DISTINCT s1.player, s1.season, s1.reboundsRatio, s2.player, s2.season, s2.reboundsRatio FROM Stats s1, Stats s2 WHERE s1.reboundsRatio >= ALL(SELECT reboundsRatio FROM Stats) AND s2.reboundsRatio <= ALL(SELECT reboundsRatio FROM Stats); -- player | season | reboundsratio | player | season | reboundsratio -- --------+--------+---------------+--------+--------+--------------- -- 203500 | 2017 | 61 | 708 | 2003 | -834 -- (1 row) -- ? 26 - Écrire une fonction qui calcule le pourcentage de joueur non américains jouant dans une -- ? équipe donnée. CREATE OR REPLACE FUNCTION PercPlayerNoAmerican(TeamId Team.id%TYPE) RETURNS numeric AS $$ DECLARE nbPlayerNoAmerican integer; nbPlayerAmerican numeric; nbPlayerTotal numeric; PercPlayerNoAmerican numeric(6,4); BEGIN SELECT count(p.id) INTO nbPlayerAmerican FROM Player p, GameDetail gd, Team t WHERE t.id = gd.idTeam AND t.id = TeamId AND gd.idPlayer = p.id AND p.country = 'USA'; SELECT count(p.id) INTO nbPlayerNoAmerican FROM Player p, GameDetail gd, Team t WHERE t.id = gd.idTeam AND t.id = TeamId AND gd.idPlayer = p.id AND p.country != 'USA'; nbPlayerTotal := nbPlayerAmerican + nbPlayerNoAmerican; PercPlayerNoAmerican := nbPlayerNoAmerican / nbPlayerTotal; RETURN PercPlayerNoAmerican * 100; END; $$ LANGUAGE plpgsql; SELECT PercPlayerNoAmerican('1610612737'); -- psql:requetesTP4-5-6.sql:499: NOTICE: type reference team.id%TYPE converted to character varying -- CREATE FUNCTION -- percplayernoamerican -- ---------------------- -- 19.3500 -- (1 row) -- ? 27 - Afficher le pourcentage de joueurs étrangers dans chaque équipe au format suivant : -- ? abbreviation | nickname | city | foreigner -- ? --------------+---------------+---------------+----------- -- ? ATL | Hawks | Atlanta | 0.12 SELECT t.abbreviation, t.nickname, t.city, PercPlayerNoAmerican(t.id) AS foreigner FROM Team t ORDER BY foreigner DESC; -- abbreviation | nickname | city | foreigner -- --------------+---------------+---------------+----------- -- SAS | Spurs | San Antonio | 39.1200 -- DAL | Mavericks | Dallas | 32.0000 -- TOR | Raptors | Toronto | 31.2100 -- UTA | Jazz | Utah | 29.1500 -- MIL | Bucks | Milwaukee | 25.8700 -- DEN | Nuggets | Denver | 25.3100 -- PHX | Suns | Phoenix | 24.9900 -- CLE | Cavaliers | Cleveland | 22.5100 -- ORL | Magic | Orlando | 21.8200 -- OKC | Thunder | Oklahoma City | 21.2400 -- MIN | Timberwolves | Minnesota | 21.1400 -- GSW | Warriors | Golden State | 20.3500 -- ATL | Hawks | Atlanta | 19.3500 -- HOU | Rockets | Houston | 18.8400 -- CHI | Bulls | Chicago | 18.5200 -- SAC | Kings | Sacramento | 18.1400 -- MEM | Grizzlies | Memphis | 17.8000 -- LAL | Lakers | Los Angeles | 16.1600 -- PHI | 76ers | Philadelphia | 16.0500 -- BKN | Nets | Brooklyn | 15.6600 -- WAS | Wizards | Washington | 15.4400 -- NOP | Pelicans | New Orleans | 15.1100 -- NYK | Knicks | New York | 14.2300 -- POR | Trail Blazers | Portland | 14.1600 -- CHA | Hornets | Charlotte | 14.1100 -- BOS | Celtics | Boston | 13.4700 -- DET | Pistons | Detroit | 12.3300 -- MIA | Heat | Miami | 11.2500 -- LAC | Clippers | Los Angeles | 10.6000 -- IND | Pacers | Indiana | 9.9200 -- (30 rows) -- ! pas le meme score !!? -- ? 28 - Dans quelle conférence, y a t’il le plus de joueurs étrangers? SELECT t.conference, PercPlayerNoAmerican(t.id) AS foreigner FROM Team t ORDER BY foreigner DESC; -- conference | foreigner -- ------------+----------- -- W | 39.1200 -- W | 32.0000 -- E | 31.2100 -- W | 29.1500 -- E | 25.8700 -- W | 25.3100 -- W | 24.9900 -- E | 22.5100 -- E | 21.8200 -- W | 21.2400 -- W | 21.1400 -- W | 20.3500 -- E | 19.3500 -- W | 18.8400 -- E | 18.5200 -- W | 18.1400 -- W | 17.8000 -- W | 16.1600 -- E | 16.0500 -- E | 15.6600 -- E | 15.4400 -- W | 15.1100 -- E | 14.2300 -- W | 14.1600 -- E | 14.1100 -- E | 13.4700 -- E | 12.3300 -- E | 11.2500 -- W | 10.6000 -- E | 9.9200 -- (30 rows) -- ? 29 - Écrire une fonction qui calcule le total de points marqués par un joueur donné. CREATE OR REPLACE FUNCTION totalPointsByPlayer(idP Player.id%TYPE) RETURNS integer AS $$ DECLARE totalPoints integer; BEGIN SELECT SUM(gd.points) INTO totalPoints FROM GameDetail gd WHERE gd.idPlayer = idP; RETURN totalPoints; END; $$ LANGUAGE plpgsql; SELECT totalPointsByPlayer('203932'); -- totalpointsbyplayer -- --------------------- -- 7263 -- (1 row) -- ? 30 - Calculer le nombre de points moyens marqués par un joueur par pays. Ordonner les résultats -- ? de façon à avoir les meilleurs pays en premier. SELECT p.country, AVG(totalPointsByPlayer(p.id)) AS average_points FROM Player p GROUP BY p.country ORDER BY average_points DESC; -- country | average_points -- ----------------------------------+------------------------ -- U.S. Virgin Islands | 13782.0000000000000000 -- Bahamas | 7640.0000000000000000 -- Cameroon | 6941.3333333333333333 -- Switzerland | 6214.0000000000000000 -- Democratic Republic of the Congo | 5333.0000000000000000 -- Spain | 5275.5000000000000000 -- Italy | 5257.3333333333333333 -- Turkey | 5235.5555555555555556 -- Germany | 5180.5454545454545455 -- Montenegro | 5139.6000000000000000 -- Slovenia | 4555.7777777777777778 -- Finland | 4270.0000000000000000 -- Bahams | 4195.0000000000000000 -- Haiti | 4188.5000000000000000 -- Dominican Republic | 4027.8000000000000000 -- Venezuela | 3935.0000000000000000 -- Serbia and Montenegro | 3877.0000000000000000 -- New Zealand | 3793.0000000000000000 -- Argentina | 3746.3636363636363636 -- Lithuania | 3579.8000000000000000 -- UK | 3133.8571428571428571 -- Poland | 3108.0000000000000000 -- Australia | 3050.7777777777777778 -- Greece | 2990.3333333333333333 -- Bosnia & Herzgovina | 2936.0000000000000000 -- France | 2909.4193548387096774 -- Brazil | 2814.3846153846153846 -- Sweden | 2641.5000000000000000 -- Serbia | 2550.9285714285714286 -- Canada | 2503.3428571428571429 -- China | 2305.0000000000000000 -- Netherlands | 2235.5000000000000000 -- Latvia | 2225.8000000000000000 -- Puerto Rico | 2104.3333333333333333 -- Israel | 2038.3333333333333333 -- Croatia | 2004.5714285714285714 -- USA | 1948.3770794824399261 -- Georgia | 1901.6000000000000000 -- Czech Republic | 1661.3333333333333333 -- Russia | 1602.4000000000000000 -- Bosnia | 1558.0000000000000000 -- Ukraine | 1331.0000000000000000 -- Belize | 1232.0000000000000000 -- St. Vincent & Grenadines | 1214.0000000000000000 -- Mexico | 1088.3333333333333333 -- Egypt | 1062.0000000000000000 -- Mali | 1030.0000000000000000 -- Macedonia | 842.0000000000000000 -- Congo | 836.5000000000000000 -- Panama | 793.0000000000000000 -- Tunisia | 763.0000000000000000 -- Nigeria | 716.2857142857142857 -- Senegal | 699.1000000000000000 -- Tanzania | 585.0000000000000000 -- South Sudan | 549.6666666666666667 -- Japan | 488.0000000000000000