|
|
\! 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 |