antoine.perederii 2 years ago
commit a5330bb1e4

@ -0,0 +1,34 @@
# CC : le compilateur à utiliser
CC=clang
# CFLAGS : les options de compilation
CFLAGS=-Wall
# Les fichiers sources : tous les fichiers présents dans src/
SRC=$(wildcard src/*.c)
# Les fichiers objets (.o)
OBJ=$(patsubst src/%.c,obj/%.o,$(SRC))
# Le répertoire où sera générée la documentation Doxygen
DOXYGEN_OUTPUT_DIR=docs
# Édition des liens : génération de l'exécutable à partir des .o
bin/exe: $(OBJ)
$(CC) $(OBJ) -o $@
# Génération des .o à partir des .c correspondants
obj/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Génération de la documentation Doxygen
doxygen:
doxygen Doxyfile
# Exécution du programme avec Valgrind
valgrind: bin/exe
valgrind --leak-check=full ./bin/exe
# Nettoyage : destruction des .o, de l'exécutable et de la documentation
clean:
rm -rf obj/*.o bin/exe $(DOXYGEN_OUTPUT_DIR)

@ -1,5 +1,8 @@
#include "abr.h"
#include <stdlib.h>
#include <stdio.h>
Abr creerArbreVide(void) {
return NULL;
}
@ -35,25 +38,21 @@ void viderArbre(Abr *pta){
*pta = NULL;
}
// void afficherCroissant(Abr a){
// printf("%d ", )
// if(a->fg != NULL) printf("%d ", a->val);
// if(a->fg == NULL) {
// printf("%d ",a->val);
// return afficherCroissant(a->fd);
// }
// else if(a->fd == NULL) return;
// else return afficherCroissant(a->fg);
// }
// void afficherDecroissant(Abr a){
// if(a->fd == NULL) {
// printf("%d ",a->val);
// return afficherDecroissant(a->fg);
// }
// else if(a->fg == NULL) return;
// else return afficherDecroissant(a->fd);
// }
void afficherCroissant(Abr a){
if(a == NULL) return;
afficherCroissant(a->fg);
printf("%d ", a->val);
afficherCroissant(a->fd);
}
void afficherDecroissant(Abr a){
if(a == NULL) return;
afficherDecroissant(a->fd);
printf("%d ", a->val);
afficherDecroissant(a->fg);
}
void afficherNtab(int n){
for(int i = 0; i<n; i++)
@ -107,7 +106,7 @@ int oterMax(Abr* pta){
Booleen supprimerVal(Abr *pta, int val){
Noeud* tmp;
if(*pta == NULL) return TRUE;
if(*pta == NULL) return FALSE;
if((*pta)->val == val){
if((*pta)->fg == NULL){

@ -1,9 +1,6 @@
#ifndef ABR_H
#define ABR_H
#include <stdio.h>
#include <stdlib.h>
typedef struct noeud {
int val;
struct noeud *fg, *fd;
@ -15,13 +12,10 @@ typedef enum{FALSE, TRUE} Booleen;
Abr creerArbreVide(void);
Booleen estArbreVide(Abr a);
Noeud* creerNoeud(int val);
void insererEnFeuille(Abr* pta, int val);
void viderArbre(Abr* pta);
// void afficherCroissant(Abr a);
// void afficherDecroissant(Abr a);
void afficherNtab(int n);
void afficherCoucheRec(Abr a, int retrait);
void afficherCroissant(Abr a);
void afficherDecroissant(Abr a);
void afficherCouche(Abr a);
Booleen rechercherVal(Abr a, int val);
Booleen supprimerVal(Abr* pta, int val);

@ -1,6 +1,11 @@
#include "abr.h"
void testArbre(void){
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void testAbr(void){
Abr a = creerArbreVide();
Abr b = creerArbreVide();
Booleen resA, resB, resRechA;
@ -38,8 +43,8 @@ void testArbre(void){
insererEnFeuille(&a, 18);
insererEnFeuille(&a, 11);
// afficherCroissant(a);
// afficherDecroissant(a);
afficherCroissant(a);
afficherDecroissant(a);
printf("\n\n");
afficherCouche(a);
printf("\n");
@ -53,10 +58,11 @@ void testArbre(void){
else printf("La valeur %d n'est pas présente dans l'arbre %c\n", val1, arbreDeRecherche);
supprimerVal(&a, 2);
printf("Valeur supprimé avec succès.");
supprimerVal(&a, 3);
}
int main(void){
testArbre();
int main(void) {
testAbr();
return 0;
}

@ -0,0 +1,34 @@
# CC : le compilateur à utiliser
CC=clang
# CFLAGS : les options de compilation
CFLAGS=-Wall
# Les fichiers sources : tous les fichiers présents dans src/
SRC=$(wildcard src/*.c)
# Les fichiers objets (.o)
OBJ=$(patsubst src/%.c,obj/%.o,$(SRC))
# Le répertoire où sera générée la documentation Doxygen
DOXYGEN_OUTPUT_DIR=docs
# Édition des liens : génération de l'exécutable à partir des .o
bin/exe: $(OBJ)
$(CC) $(OBJ) -o $@
# Génération des .o à partir des .c correspondants
obj/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Génération de la documentation Doxygen
doxygen:
doxygen Doxyfile
# Exécution du programme avec Valgrind
valgrind: bin/exe
valgrind --leak-check=full ./bin/exe
# Nettoyage : destruction des .o, de l'exécutable et de la documentation
clean:
rm -rf obj/*.o bin/exe $(DOXYGEN_OUTPUT_DIR)

Binary file not shown.

@ -0,0 +1,199 @@
#include "avl.h"
#include <stdio.h>
#include <stdlib.h>
Avl creerAvlVide(void) {
return NULL;
}
Booleen estAvlVide(Avl a){
if(a == NULL) return TRUE;
return FALSE;
}
void viderAvl(Avl *pta){
if(*pta == NULL) return;
viderAvl(&(*pta)->fg);
viderAvl(&(*pta)->fd);
free(*pta);
*pta = NULL;
}
void afficherCroissantAvl(Avl a){
if(a == NULL) return;
afficherCroissantAvl(a->fg);
printf("%d ", a->val);
afficherCroissantAvl(a->fd);
}
void afficherDecroissantAvl(Avl a){
if(a == NULL) return;
afficherDecroissantAvl(a->fd);
printf("%d ", a->val);
afficherDecroissantAvl(a->fg);
}
void afficherNtabAvl(int n){
for(int i = 0; i<n; i++)
printf("\t");
}
void afficherCoucheRecAvl(Avl a, int retrait){
if(a->fd != NULL){
afficherCoucheRecAvl(a->fd, retrait+1);
afficherNtabAvl(retrait); printf(" / \n");
}
afficherNtabAvl(retrait); printf("%d\n", a->val);
if(a->fg != NULL){
afficherNtabAvl(retrait); printf(" \\ \n");
afficherCoucheRecAvl(a->fg, retrait+1);
}
}
void afficherCoucheAvl(Avl a){
if(a!=NULL) {
printf("==================== Affichage ====================\n");
afficherCoucheRecAvl(a,0);
printf("==================== Fin Affichage ====================\n");
}
}
Booleen rechercherValAvl(Avl a, int val){
Booleen rep;
if(a == NULL) return FALSE;
if(a->val == val) return TRUE;
rep = rechercherValAvl(a->fg, val);
if(rep == FALSE || !rep)
rep = rechercherValAvl(a->fd, val);
return rep;
}
void mettreAjourHauteur(Noeud* ptn) {
int hg, hd;
hg = (ptn->fg==NULL)? -1 : ptn->fd->h;
hd = (ptn->fd==NULL)? -1 : ptn->fd->h;
ptn->h = (hg>hd)? 1+hg : 1+hd;
}
void rotationGauche(Avl *pta) {
Noeud* racine;
racine = (*pta)->fd;
(*pta)->fd = racine->fg;
racine->fg = *pta;
*pta = racine;
mettreAjourHauteur((*pta)->fg);
mettreAjourHauteur(*pta);
}
void rotationDroite(Avl *pta) {
Noeud* racine;
racine = (*pta)->fg;
(*pta)->fg = racine->fd;
racine->fd = *pta;
*pta = racine;
mettreAjourHauteur((*pta)->fd);
mettreAjourHauteur(*pta);
}
void reequilibrer(Avl* pta) {
int hg, hd, hgf, hdf;
hg = ((*pta)->fg != NULL)? (*pta)->fg->h : -1;
hd = ((*pta)->fd != NULL)? (*pta)->fd->h : -1;
if (hg - hd == 2){ // déséquilibre : hg > hd de 2
hgf = ((*pta)->fg->fg != NULL)? (*pta)->fg->fg->h : -1;
hdf = ((*pta)->fg->fd != NULL)? (*pta)->fg->fd->h : -1;
if (hdf > hgf) rotationGauche (& (*pta)->fg);
rotationDroite (pta);
}
else if(hd - hg == 2){ // déséquilibre : hd > hg de 2
hgf = ((*pta)->fd->fg != NULL)? (*pta)->fd->fg->h : -1;
hdf = ((*pta)->fd->fd != NULL)? (*pta)->fd->fd->h :
-1;
if (hgf > hdf) rotationDroite (& (*pta)->fd);
rotationGauche (pta);
}
else{ // pas de déséquilibre, on remet juste la hauteur à jour
if (hd > hg) (*pta) ->h = hd+1;
else (*pta) ->h = hg+1;
}
}
Noeud* creerNoeudAvl(int val){
Noeud* tmp = (Noeud*)malloc(sizeof(Noeud));
if(tmp == NULL) exit(1);
tmp->val = val;
tmp->h = 0;
tmp->fd = NULL;
tmp->fg = NULL;
return tmp;
}
void insererEquilibre(Avl* pta, int val) {
if(*pta == NULL)
*pta = creerNoeudAvl(val);
else {
if(val <= (*pta)->val)
insererEquilibre(&(*pta)->fg, val);
else
insererEquilibre(&(*pta)->fd, val);
reequilibrer(pta);
}
}
int oterMaxEquilibre(Avl* pta){
Noeud* tmp;
int val;
if((*pta)->fd == NULL){
tmp = *pta;
val = tmp->val;
*pta = (*pta)->fg;
free(tmp);
}
else{
val = oterMaxEquilibre(&(*pta)->fd);
reequilibrer(pta);
}
return val;
}
Booleen supprimerValEquilibre(Avl *pta, int val){
Noeud* tmp;
Booleen b;
if(*pta == NULL) return FALSE;
if((*pta)->val == val){
if((*pta)->fg == NULL){
tmp = *pta;
*pta = (*pta)->fd; //! si fd est aussi nul, alors *pta sera null !
free(tmp);
}
else if((*pta)->fd == NULL){
tmp = *pta;
*pta = (*pta)->fg;
free(tmp);
}
else{
(*pta)->val = oterMaxEquilibre(&(*pta)->fg);
reequilibrer(pta);
}
return TRUE;
}
//sinon on continue dans la suite de l'arbre
else {
if(val < (*pta)->val)
b = supprimerValEquilibre(&(*pta)->fg, val);
else
b = supprimerValEquilibre(&(*pta)->fd, val);
if(b) reequilibrer(pta);
}
return b;
}

@ -0,0 +1,27 @@
#ifndef AVL_H
#define AVL_H
typedef struct noeud {
int val;
int h;
struct noeud *fg, *fd;
} Noeud;
typedef Noeud* Avl;
typedef enum{FALSE, TRUE} Booleen;
Avl creerAvlVide(void);
Booleen estAvlVide(Avl a);
void viderAvl(Avl *pta);
void afficherCroissantAvl(Avl a);
void afficherDecroissantAvl(Avl a);
void afficherCoucheAvl(Avl a);
Booleen rechercherValAvl(Avl a, int val);
void insererEquilibre(Avl* pta, int val);
Booleen supprimerValEquilibre(Avl* pta, int val);
#endif //AVL_H

@ -0,0 +1,82 @@
#include "avl.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void testAvl(void) {
Avl a = creerAvlVide();
Avl b = creerAvlVide();
Booleen resA, resB, resSupA;
if(a == NULL && b == NULL) printf("Arbre créée avec succès.\n");
else {
printf("Erreur lors de la création de l'arbre !\n");
exit(1);
}
resA = estAvlVide(a);
resB = estAvlVide(b);
if(resA == TRUE && resB == TRUE) printf("Aucun Pb, les arbres sont bien vides.\n");
else printf("Pb, arbres non vide !\n");
insererEquilibre(&a, 7);
insererEquilibre(&a, 9);
insererEquilibre(&a, 8);
insererEquilibre(&a, 6);
resA = estAvlVide(a);
if(resA == TRUE) printf("Erreur, l'abre incrémenté est vide !\n");
else printf("Aucun pb.\n");
viderAvl(&a);
resA = estAvlVide(a);
if(resA == TRUE) printf("Tout fonctionne, l'arbre A est bien vidé.\n");
else printf("Pb, l'arbre a n'a pas été vidé correctement !\n");
insererEquilibre(&a, 7);
insererEquilibre(&a, 9);
insererEquilibre(&a, 8);
insererEquilibre(&a, 6);
insererEquilibre(&a, 1);
insererEquilibre(&a, 2);
insererEquilibre(&a, 18);
insererEquilibre(&a, 11);
afficherCoucheAvl(a);
// afficherCroissant(a);
// afficherDecroissant(a);
resSupA = supprimerValEquilibre(&a, 2);
if(resSupA == 1) printf("Suppression efféctuée avec succès.");
else printf("Pb suppression.");
afficherCoucheAvl(a);
insererEquilibre(&a, 19);
insererEquilibre(&a, 20);
insererEquilibre(&a, 21);
afficherCoucheAvl(a);
afficherCroissantAvl(a);
printf("\n");
afficherDecroissantAvl(a);
printf("\n");
// printf("%d", resSupA);
}
// void testTempAvl(void){
// int insertion, deb;
// deb = time();
// Avl a = creerAvlVide();
// for(int i = 1; i < 10000; i++) {
// insererEquilibre(&a, i);
// }
// insertion = time() - deb;
// printf("%d \n", insertion);
// }
int main(void) {
testAvl();
// testTempAvl();
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -72,155 +72,4 @@ CREATE TABLE GameDetail(
\i players.sql
\i teams.sql
\i games.sql
\i games-details.sql
--? 2 - Dans quelle ville est située léquipe surnommée les Grizzlies?
-- SELECT city
-- FROM TEAM
-- WHERE nickname = 'Grizzlies';
-- city
-- ---------
-- Memphis
-- (1 row)
--? 3 - Quel est le plus gros score marqué à domicile par une équipe?
-- SELECT max(ptsHome)
-- FROM Game;
-- max
-- -----
-- 168
-- (1 row)
--? 4 - Quel est le plus gros score marqué à lextérieur par une équipe?
-- SELECT max(ptsAway)
-- FROM Game;
-- max
-- -----
-- 168
-- (1 row)
--? 5 - Le résultat obtenu devrait être surprenant. Justifier que vos réponses aux deux dernières
--? questions sont correctes.
-- Le resultat est le même entre à domicile et à l'exterieur. Les scores ont du être réalisé sur deux match différents mais ils ont le même max.
-- SELECT 'Points max à domicile : ' || max(ptsHome) || 'Avec pour id de game : ' || id
-- FROM Game
-- GROUP BY ptsHome, id;
-- ?column?
-- ------------------------------------------------------------
-- Points max à domicile : 93Avec pour id de game : 21200728
-- Points max à domicile : 106Avec pour id de game : 20501075
-- Points max à domicile : 94Avec pour id de game : 22000463
-- Points max à domicile : 94Avec pour id de game : 21600817
-- Points max à domicile : 103Avec pour id de game : 20700669
-- Points max à domicile : 129Avec pour id de game : 20800711
-- Points max à domicile : 106Avec pour id de game : 21000744
-- Points max à domicile : 106Avec pour id de game : 20901056
-- Points max à domicile : 101Avec pour id de game : 20600197
-- SELECT 'Points max à exterieur : ' || max(ptsAway) || 'Avec pour id de game : ' || id
-- FROM Game
-- GROUP BY ptsAway, id;
-- ?column?
-- -------------------------------------------------------------
-- Points max à exterieur : 84Avec pour id de game : 21200728
-- Points max à exterieur : 94Avec pour id de game : 20501075
-- Points max à exterieur : 96Avec pour id de game : 22000463
-- Points max à exterieur : 90Avec pour id de game : 21600817
-- Points max à exterieur : 116Avec pour id de game : 20700669
--? 6 - Quelle équipe a marqué le plus de points à domicile, indiquez labbréviation, le nickname, la ville, les points marqués et la date du match ?
-- SELECT abbreviation, nickname, city, ptsHome, dateGame
-- FROM Team t, Game g
-- WHERE t.id = g.idHomeTeam AND g.ptsHome = (SELECT max(ptsHome)
-- FROM Game);
-- abbreviation | nickname | city | ptshome | dategame
-- --------------+----------+--------+---------+------------
-- DEN | Nuggets | Denver | 168 | 2008-03-16
-- (1 row)
--? 7 - Même pour l'exterieur
-- SELECT abbreviation, nickname, city, ptsAway, dateGame
-- FROM Team t, Game g
-- WHERE t.id = g.idVisitorTeam AND g.ptsAway = (SELECT max(ptsAway)
-- FROM Game);
-- abbreviation | nickname | city | ptsaway | dategame
-- --------------+----------+---------+---------+------------
-- CHI | Bulls | Chicago | 168 | 2019-03-01
-- (1 row)
--? 8 - Quels sont les noms des joueurs qui ont le plus gros pourcentage de paniers à trois points dans un match ?
-- SELECT p.name, max(threePointsPrctage)
-- FROM Player p, GameDetail gd
-- WHERE p.id = gd.idPlayer AND gd.threePointsPrctage = (SELECT max(threePointsPrctage)
-- FROM GameDetail)
-- GROUP BY name, threePointsPrctage;
-- name | max
-- --------------------------+-----
-- Malcolm Hill | 1
-- Rajon Rondo | 1
-- Kobi Simmons | 1
-- Derrick Jones Jr. | 1
-- Scott Williams | 1
-- Isaiah Joe | 1
-- Jarrell Brantley | 1
-- Tahjere McCall | 1
-- Jeremy Senglin | 1
--? 9 - Quels sont les joueurs qui ont la moyenne la plus élevée de pourcentage de paniers à trois points sur tous les matchs ?
SELECT p.id, avg(threePointsPrctage)
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND avg(threePointsPrctage) >= ALL(SELECT avg(threePointsPrctage)
FROM GameDetail)
GROUP BY p.id, threePointsPrctage
ORDER BY threePointsPrctage ASC;
--? 10 - Pour la saison 2012, calculer quel est le plus grand nombre de paniers à 3 points marqués par un joueur.
SELECT max(threePointsMade), g.season, p.name
FROM GameDetail gd, Game g, Player p
WHERE gd.idGame = g.id AND gd.idPlayer = p.id AND g.season = '2012'
GROUP BY threePointsMade, season, p.name
ORDER BY threePointsMade DESC;
--? 11 - Pour chaque conférence, quelle équipe (nom et ville) est la dernière à avoir rejoint la NBA en indiquant lannée darrivée en NBA ?
--? (Faire une seule requête pour les deux conférences, et non pas une requête par conférence.)
SELECT nickname, city
FROM Team t, Game g, GameDetail gd
WHERE t.id = gd.idTeam AND gd.idGame = g.id
GROUP BY g.season
HAVING max(season) - min(season) IN(SELECT max(max(season) - min(season)) FROM Game);
--? 12 - Quel est le nom du joueur qui a fait le plus de passes décisives dans un match? Donner la date de son exploit.
SELECT p.name, gd.turnovers, g.dateGame
FROM Player p, GameDetail gd, Game g
WHERE p.id = gd.idPlayer AND gd.idGame = g.id AND gd.turnovers >= ALL(SELECT gd.turnovers
FROM GameDetail);
--? 13 - Quel est le joueur qui a fait le plus rapidement 6 fautes personnelles ? Donner la date de cette performance et le nom du joueur.
-- SELECT p.name, gd.playingTime, gd.personnalFoul
-- FROM Player p, GameDetail gd
-- WHERE p.id = gd.idPlayer AND gd.playingTime <= ALL(SELECT playingTime FROM GameDetail WHERE personnalFoul = 6) AND gd.personnalFoul = 6;
-- name | playingtime | personnalfoul
-- ---------------+-------------+---------------
-- Sean Williams | 00:02:00 | 6
-- (1 row)
--? 14 - Même question, mais on veut désormais les deux équipes qui se sont affrontées lors de ce match.
--? 15 - Écrire la requête permettant dafficher la liste des joueurs qui ont fait un triple double dans
--? leur carrière en donnant leurs statistiques dans les 5 catégories. Un triple double cest avoir au moins
--? dans 3 catégories des statistiques à 2 chiffres (points, rebonds, passes, contres, interceptions) dans un même match.
--? 16 - Écrire la requête permettant dafficher la liste des joueurs qui ont fait plus dinterception que de
--? balles perdues et qui ont intercepté plus de 1000 balles dans leur carrière.
\i games-details.sql

@ -0,0 +1,152 @@
\! clear
--? 2 - Dans quelle ville est située léquipe surnommée les Grizzlies?
-- SELECT city
-- FROM TEAM
-- WHERE nickname = 'Grizzlies';
-- city
-- ---------
-- Memphis
-- (1 row)
--? 3 - Quel est le plus gros score marqué à domicile par une équipe?
-- SELECT max(ptsHome)
-- FROM Game;
-- max
-- -----
-- 168
-- (1 row)
--? 4 - Quel est le plus gros score marqué à lextérieur par une équipe?
-- SELECT max(ptsAway)
-- FROM Game;
-- max
-- -----
-- 168
-- (1 row)
--? 5 - Le résultat obtenu devrait être surprenant. Justifier que vos réponses aux deux dernières
--? questions sont correctes.
-- Le resultat est le même entre à domicile et à l'exterieur. Les scores ont du être réalisé sur deux match différents mais ils ont le même max.
-- SELECT 'Points max à domicile : ' || max(ptsHome) || 'Avec pour id de game : ' || id
-- FROM Game
-- GROUP BY ptsHome, id;
-- ?column?
-- ------------------------------------------------------------
-- Points max à domicile : 93Avec pour id de game : 21200728
-- Points max à domicile : 106Avec pour id de game : 20501075
-- Points max à domicile : 94Avec pour id de game : 22000463
-- Points max à domicile : 94Avec pour id de game : 21600817
-- Points max à domicile : 103Avec pour id de game : 20700669
-- Points max à domicile : 129Avec pour id de game : 20800711
-- Points max à domicile : 106Avec pour id de game : 21000744
-- Points max à domicile : 106Avec pour id de game : 20901056
-- Points max à domicile : 101Avec pour id de game : 20600197
-- SELECT 'Points max à exterieur : ' || max(ptsAway) || 'Avec pour id de game : ' || id
-- FROM Game
-- GROUP BY ptsAway, id;
-- ?column?
-- -------------------------------------------------------------
-- Points max à exterieur : 84Avec pour id de game : 21200728
-- Points max à exterieur : 94Avec pour id de game : 20501075
-- Points max à exterieur : 96Avec pour id de game : 22000463
-- Points max à exterieur : 90Avec pour id de game : 21600817
-- Points max à exterieur : 116Avec pour id de game : 20700669
--? 6 - Quelle équipe a marqué le plus de points à domicile, indiquez labbréviation, le nickname, la ville, les points marqués et la date du match ?
-- SELECT abbreviation, nickname, city, ptsHome, dateGame
-- FROM Team t, Game g
-- WHERE t.id = g.idHomeTeam AND g.ptsHome = (SELECT max(ptsHome)
-- FROM Game);
-- abbreviation | nickname | city | ptshome | dategame
-- --------------+----------+--------+---------+------------
-- DEN | Nuggets | Denver | 168 | 2008-03-16
-- (1 row)
--? 7 - Même pour l'exterieur
-- SELECT abbreviation, nickname, city, ptsAway, dateGame
-- FROM Team t, Game g
-- WHERE t.id = g.idVisitorTeam AND g.ptsAway = (SELECT max(ptsAway)
-- FROM Game);
-- abbreviation | nickname | city | ptsaway | dategame
-- --------------+----------+---------+---------+------------
-- CHI | Bulls | Chicago | 168 | 2019-03-01
-- (1 row)
--? 8 - Quels sont les noms des joueurs qui ont le plus gros pourcentage de paniers à trois points dans un match ?
-- SELECT p.name, max(threePointsPrctage)
-- FROM Player p, GameDetail gd
-- WHERE p.id = gd.idPlayer AND gd.threePointsPrctage = (SELECT max(threePointsPrctage)
-- FROM GameDetail)
-- GROUP BY name, threePointsPrctage;
-- name | max
-- --------------------------+-----
-- Malcolm Hill | 1
-- Rajon Rondo | 1
-- Kobi Simmons | 1
-- Derrick Jones Jr. | 1
-- Scott Williams | 1
-- Isaiah Joe | 1
-- Jarrell Brantley | 1
-- Tahjere McCall | 1
-- Jeremy Senglin | 1
--? 9 - Quels sont les joueurs qui ont la moyenne la plus élevée de pourcentage de paniers à trois points sur tous les matchs ?
-- SELECT p.id, avg(threePointsPrctage)
-- FROM Player p, GameDetail gd
-- WHERE p.id = gd.idPlayer AND avg(threePointsPrctage) >= ALL(SELECT avg(threePointsPrctage)
-- FROM GameDetail)
-- GROUP BY p.id, threePointsPrctage
-- ORDER BY threePointsPrctage ASC;
-- --? 10 - Pour la saison 2012, calculer quel est le plus grand nombre de paniers à 3 points marqués par un joueur.
-- SELECT max(threePointsMade), g.season, p.name
-- FROM GameDetail gd, Game g, Player p
-- WHERE gd.idGame = g.id AND gd.idPlayer = p.id AND g.season = '2012'
-- GROUP BY threePointsMade, season, p.name
-- ORDER BY threePointsMade DESC;
-- --? 11 - Pour chaque conférence, quelle équipe (nom et ville) est la dernière à avoir rejoint la NBA en indiquant lannée darrivée en NBA ?
-- --? (Faire une seule requête pour les deux conférences, et non pas une requête par conférence.)
-- SELECT nickname, city
-- FROM Team t, Game g, GameDetail gd
-- WHERE t.id = gd.idTeam AND gd.idGame = g.id
-- GROUP BY g.season
-- HAVING max(season) - min(season) IN(SELECT max(max(season) - min(season)) FROM Game);
-- --? 12 - Quel est le nom du joueur qui a fait le plus de passes décisives dans un match? Donner la date de son exploit.
-- SELECT p.name, gd.turnovers, g.dateGame
-- FROM Player p, GameDetail gd, Game g
-- WHERE p.id = gd.idPlayer AND gd.idGame = g.id AND gd.turnovers >= ALL(SELECT gd.turnovers
-- FROM GameDetail);
--? 13 - Quel est le joueur qui a fait le plus rapidement 6 fautes personnelles ? Donner la date de cette performance et le nom du joueur.
-- SELECT p.name, gd.playingTime, gd.personnalFoul
-- FROM Player p, GameDetail gd
-- WHERE p.id = gd.idPlayer AND gd.playingTime <= ALL(SELECT playingTime FROM GameDetail WHERE personnalFoul = 6) AND gd.personnalFoul = 6;
-- name | playingtime | personnalfoul
-- ---------------+-------------+---------------
-- Sean Williams | 00:02:00 | 6
-- (1 row)
--? 14 - Même question, mais on veut désormais les deux équipes qui se sont affrontées lors de ce match.
--? 15 - Écrire la requête permettant dafficher la liste des joueurs qui ont fait un triple double dans
--? leur carrière en donnant leurs statistiques dans les 5 catégories. Un triple double cest avoir au moins
--? dans 3 catégories des statistiques à 2 chiffres (points, rebonds, passes, contres, interceptions) dans un même match.
--? 16 - Écrire la requête permettant dafficher la liste des joueurs qui ont fait plus dinterception que de
--? balles perdues et qui ont intercepté plus de 1000 balles dans leur carrière.

@ -0,0 +1,650 @@
--? 1 - Lobjectif de ce TP étant détudier loptimisation et les index,
--? mettez à jour les statistiques utilisées par PostgreSQL pour établir les plans dexécution afin de partir sur de bonnes bases.
-- TODO : ANALYZE table_name;
ANALYSE; -- Pour tout d'un coup.
--? 2 - Lors du TP précédent, vous avez écrit une requête permettant de répondre à la question
--? suivante :
--? Quel est le joueur qui a fait le plus rapidement 6 fautes personnelles ? Donner la date de cette performance et le nom des deux équipes qui se sont affrontées lors de ce match.
--? Afficher le plan dexécution détaillé avec le temps dexécution de cette requête.
EXPLAIN ANALYZE
SELECT p.name , t1.abbreviation , t2.abbreviation , g.dateGame
FROM Player p, Team t1, Team t2, GameDetail gd, Game g
WHERE p.id = gd.idPlayer AND g.id = gd.idGame AND t1.id = gd.idTeam
AND ((g.idHomeTeam = t1.id AND g.idVisitorTeam = t2.id)
OR (g.idVisitorTeam = t1.id AND g.idHomeTeam = t2.id))
AND gd.personnalFoul > 6;
-- QUERY PLAN
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Nested Loop (cost=1001.37..16948.56 rows=1 width=49) (actual time=85.074..86.860 rows=1 loops=1)
-- Join Filter: ((((g.idhometeam)::text = (t1.id)::text) AND ((g.idvisitorteam)::text = (t2.id)::text)) OR (((g.idvisitorteam)::text = (t1.id)::text) AND ((g.idhometeam)::text = (t2.id)::text)))
-- Rows Removed by Join Filter: 1
-- -> Nested Loop (cost=1000.97..16940.34 rows=1 width=93) (actual time=85.034..86.818 rows=1 loops=1)
-- Join Filter: ((gd.idteam)::text = (t1.id)::text)
-- -> Nested Loop (cost=1000.57..16933.54 rows=1 width=50) (actual time=84.985..86.769 rows=1 loops=1)
-- -> Nested Loop (cost=1000.28..16925.24 rows=1 width=33) (actual time=84.973..86.756 rows=1 loops=1)
-- -> Gather (cost=1000.00..16916.93 rows=1 width=26) (actual time=83.900..85.640 rows=1 loops=1)
-- Workers Planned: 2
-- Workers Launched: 2
-- -> Parallel Seq Scan on gamedetail gd (cost=0.00..15916.83 rows=1 width=26) (actual time=56.639..67.325 rows=0 loops=3)
-- Filter: (personnalfoul > '6'::numeric)
-- Rows Removed by Filter: 215221
-- -> Index Scan using player_pkey on player p (cost=0.28..8.30 rows=1 width=19) (actual time=1.005..1.005 rows=1 loops=1)
-- Index Cond: ((id)::text = (gd.idplayer)::text)
-- -> Index Scan using game_pkey on game g (cost=0.29..8.30 rows=1 width=35) (actual time=0.008..0.008 rows=1 loops=1)
-- Index Cond: (id = gd.idgame)
-- -> Bitmap Heap Scan on team t1 (cost=0.40..4.42 rows=190 width=54) (actual time=0.012..0.012 rows=1 loops=1)
-- Recheck Cond: (((g.idhometeam)::text = (id)::text) OR ((g.idvisitorteam)::text = (id)::text))
-- Heap Blocks: exact=1
-- -> BitmapOr (cost=0.40..0.40 rows=2 width=0) (actual time=0.007..0.008 rows=0 loops=1)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.005..0.005 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idhometeam)::text)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idvisitorteam)::text)
-- -> Bitmap Heap Scan on team t2 (cost=0.40..4.42 rows=190 width=54) (actual time=0.003..0.004 rows=2 loops=1)
-- Recheck Cond: (((g.idvisitorteam)::text = (id)::text) OR ((g.idhometeam)::text = (id)::text))
-- Heap Blocks: exact=1
-- -> BitmapOr (cost=0.40..0.40 rows=2 width=0) (actual time=0.003..0.003 rows=0 loops=1)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idvisitorteam)::text)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idhometeam)::text)
-- Planning Time: 1.956 ms
-- Execution Time: 87.197 ms
-- (35 rows)
--? 3 - En indexant une colonne, il est possible de grandement améliorer le temps dexécution de la requête. Laquelle ? Tester et comparer le temps dexécution.
CREATE INDEX idx ON GameDetail(personnalFoul);
EXPLAIN ANALYZE
SELECT p.name , t1.abbreviation , t2.abbreviation , g.dateGame
FROM Player p, Team t1, Team t2, GameDetail gd, Game g
WHERE p.id = gd.idPlayer AND g.id = gd.idGame AND t1.id = gd.idTeam
AND ((g.idHomeTeam = t1.id AND g.idVisitorTeam = t2.id)
OR (g.idVisitorTeam = t1.id AND g.idHomeTeam = t2.id))
AND gd.personnalFoul > 6;
-- QUERY PLAN
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Nested Loop (cost=1.79..40.07 rows=1 width=49) (actual time=0.201..0.214 rows=1 loops=1)
-- Join Filter: ((((g.idhometeam)::text = (t1.id)::text) AND ((g.idvisitorteam)::text = (t2.id)::text)) OR (((g.idvisitorteam)::text = (t1.id)::text) AND ((g.idhometeam)::text = (t2.id)::text)))
-- Rows Removed by Join Filter: 1
-- -> Nested Loop (cost=1.39..31.85 rows=1 width=93) (actual time=0.174..0.183 rows=1 loops=1)
-- Join Filter: ((gd.idteam)::text = (t1.id)::text)
-- -> Nested Loop (cost=0.99..25.05 rows=1 width=50) (actual time=0.128..0.134 rows=1 loops=1)
-- -> Nested Loop (cost=0.71..16.75 rows=1 width=33) (actual time=0.093..0.097 rows=1 loops=1)
-- -> Index Scan using idx on gamedetail gd (cost=0.42..8.44 rows=1 width=26) (actual time=0.044..0.046 rows=1 loops=1)
-- Index Cond: (personnalfoul > '6'::numeric)
-- -> Index Scan using player_pkey on player p (cost=0.28..8.30 rows=1 width=19) (actual time=0.031..0.032 rows=1 loops=1)
-- Index Cond: ((id)::text = (gd.idplayer)::text)
-- -> Index Scan using game_pkey on game g (cost=0.29..8.30 rows=1 width=35) (actual time=0.029..0.030 rows=1 loops=1)
-- Index Cond: (id = gd.idgame)
-- -> Bitmap Heap Scan on team t1 (cost=0.40..4.42 rows=190 width=54) (actual time=0.032..0.035 rows=1 loops=1)
-- Recheck Cond: (((g.idhometeam)::text = (id)::text) OR ((g.idvisitorteam)::text = (id)::text))
-- Heap Blocks: exact=1
-- -> BitmapOr (cost=0.40..0.40 rows=2 width=0) (actual time=0.020..0.022 rows=0 loops=1)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.012..0.012 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idhometeam)::text)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.003..0.003 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idvisitorteam)::text)
-- -> Bitmap Heap Scan on team t2 (cost=0.40..4.42 rows=190 width=54) (actual time=0.012..0.014 rows=2 loops=1)
-- Recheck Cond: (((g.idvisitorteam)::text = (id)::text) OR ((g.idhometeam)::text = (id)::text))
-- Heap Blocks: exact=1
-- -> BitmapOr (cost=0.40..0.40 rows=2 width=0) (actual time=0.009..0.010 rows=0 loops=1)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.004..0.004 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idvisitorteam)::text)
-- -> Bitmap Index Scan on team_pkey (cost=0.00..0.15 rows=1 width=0) (actual time=0.003..0.003 rows=1 loops=1)
-- Index Cond: ((id)::text = (g.idhometeam)::text)
-- Planning Time: 2.722 ms
-- Execution Time: 0.558 ms
-- (31 rows)
--? 4 - Trouver le nom de léquipe ayant gagné un match avec le plus grand écart de points, avec le score final.
SELECT t1.nickname, abs(g.ptsAway - g.ptsHome), ptsAway, ptsHome
FROM Team t1, Team t2, Game g
WHERE t1.id = g.idHomeTeam AND t2.id = g.idVisitorTeam AND g.homeTeamWins = TRUE
GROUP BY t1.nickname, abs(g.ptsAway - g.ptsHome), ptsAway, ptsHome
HAVING abs(g.ptsAway - g.ptsHome) >= ALL(SELECT abs(g.ptsAway - g.ptsHome)
FROM Team t3, Team t4, Game g
WHERE t3.id = g.idHomeTeam AND t4.id = g.idVisitorTeam AND g.homeTeamWins = true);
-- nickname | abs | ptsaway | ptshome
-- -----------+-----+---------+---------
-- Grizzlies | 73 | 79 | 152
-- (1 row)
--? 5 - Analyser le plan dexécution.
--! devrait marcher normalement (sans HAVING)==> OUI
--? Mais change pas grand chose ????!!!!
EXPLAIN ANALYZE
SELECT t1.nickname, abs(g.ptsAway - g.ptsHome), ptsAway, ptsHome
FROM Team t1, Team t2, Game g
WHERE t1.id = g.idHomeTeam AND t2.id = g.idVisitorTeam AND g.homeTeamWins = TRUE
AND abs(g.ptsAway - g.ptsHome) >= ALL(SELECT abs(g.ptsAway - g.ptsHome)
FROM Team t1, Team t2, Game g
WHERE t1.id = g.idHomeTeam AND t2.id = g.idVisitorTeam AND g.homeTeamWins = true);
EXPLAIN ANALYZE
-- SELECT t1.nickname, abs(g.ptsAway - g.ptsHome), ptsAway, ptsHome
-- FROM Team t1, Team t2, Game g
-- WHERE t1.id = g.idHomeTeam AND t2.id = g.idVisitorTeam AND g.homeTeamWins = TRUE
-- GROUP BY t1.nickname, abs(g.ptsAway - g.ptsHome), ptsAway, ptsHome
-- HAVING abs(g.ptsAway - g.ptsHome) >= ALL(SELECT abs(g.ptsAway - g.ptsHome)
-- FROM Team t1, Team t2, Game g
-- WHERE t1.id = g.idHomeTeam AND t2.id = g.idVisitorTeam AND g.homeTeamWins = true);
-- QUERY PLAN
-- ----------------------------------------------------------------------------------------------------------------------------------------
-- HashAggregate (cost=1065.09..7344429.42 rows=7569 width=120) (actual time=73.608..80.050 rows=1 loops=1)
-- Group Key: t1.nickname, abs((g.ptsaway - g.ptshome)), g.ptsaway, g.ptshome
-- Filter: (SubPlan 1)
-- Batches: 1 Memory Usage: 1433kB
-- Rows Removed by Filter: 11863
-- -> Hash Join (cost=28.55..885.16 rows=15138 width=120) (actual time=0.139..26.082 rows=15138 loops=1)
-- Hash Cond: ((g.idvisitorteam)::text = (t2.id)::text)
-- -> Hash Join (cost=14.28..754.57 rows=15138 width=99) (actual time=0.060..15.497 rows=15138 loops=1)
-- Hash Cond: ((g.idhometeam)::text = (t1.id)::text)
-- -> Seq Scan on game g (cost=0.00..699.67 rows=15138 width=32) (actual time=0.014..8.369 rows=15138 loops=1)
-- Filter: hometeamwins
-- Rows Removed by Filter: 10629
-- -> Hash (cost=11.90..11.90 rows=190 width=116) (actual time=0.027..0.027 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Seq Scan on team t1 (cost=0.00..11.90 rows=190 width=116) (actual time=0.004..0.012 rows=30 loops=1)
-- -> Hash (cost=11.90..11.90 rows=190 width=38) (actual time=0.054..0.054 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Seq Scan on team t2 (cost=0.00..11.90 rows=190 width=38) (actual time=0.024..0.032 rows=30 loops=1)
-- SubPlan 1
-- -> Materialize (cost=28.55..960.85 rows=15138 width=32) (actual time=0.000..0.002 rows=9 loops=11864)
-- -> Hash Join (cost=28.55..885.16 rows=15138 width=32) (actual time=0.096..14.368 rows=15138 loops=1)
-- Hash Cond: ((g_1.idvisitorteam)::text = (t2_1.id)::text)
-- -> Hash Join (cost=14.28..754.57 rows=15138 width=21) (actual time=0.032..8.845 rows=15138 loops=1)
-- Hash Cond: ((g_1.idhometeam)::text = (t1_1.id)::text)
-- -> Seq Scan on game g_1 (cost=0.00..699.67 rows=15138 width=32) (actual time=0.010..5.103 rows=15138 loops=1)
-- Filter: hometeamwins
-- Rows Removed by Filter: 10629
-- -> Hash (cost=11.90..11.90 rows=190 width=38) (actual time=0.016..0.016 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Seq Scan on team t1_1 (cost=0.00..11.90 rows=190 width=38) (actual time=0.002..0.009 rows=30 loops=1)
-- -> Hash (cost=11.90..11.90 rows=190 width=38) (actual time=0.039..0.039 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Seq Scan on team t2_1 (cost=0.00..11.90 rows=190 width=38) (actual time=0.028..0.032 rows=30 loops=1)
-- Planning Time: 0.916 ms
-- Execution Time: 80.363 ms
-- (35 rows)
--! Optimiser le JOIN
--? 6 - Comment améliorer les performances de cette requête ? Tester et comparer. ==> But : faire des index
CREATE INDEX idx2 ON Game(idHomeTeam, idVisitorTeam);
--? 7 - Trouver les joueurs ayant fait plus de 5 interceptions (steal) tout en ayant commencé au centre.
SELECT p.id, p.name
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND gd.steals >= 5 AND gd.startposition = 'C';
-- id | name
-- ---------+---------------------
-- 1630596 | Evan Mobley
-- 1628389 | Bam Adebayo
-- 202326 | DeMarcus Cousins
-- 203991 | Clint Capela
-- 1628389 | Bam Adebayo
-- 203083 | Andre Drummond
-- 202696 | Nikola Vucevic
-- 203110 | Draymond Green
-- 203083 | Andre Drummond
-- 203954 | Joel Embiid
-- 202326 | DeMarcus Cousins
-- 1628976 | Wendell Carter Jr.
-- 202696 | Nikola Vucevic
-- 203999 | Nikola Jokic
-- 1626167 | Myles Turner
-- 203496 | Robert Covington
--? 8 - Analyser le plan dexécution
EXPLAIN ANALYZE
SELECT p.id, p.name
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND gd.steals >= 5 AND gd.startposition = 'C';
-- QUERY PLAN
-- -------------------------------------------------------------------------------------------------------------------------------------
-- Gather (cost=1000.28..17684.64 rows=201 width=19) (actual time=1.410..80.509 rows=137 loops=1)
-- Workers Planned: 2
-- Workers Launched: 2
-- -> Nested Loop (cost=0.28..16664.54 rows=84 width=19) (actual time=2.226..64.468 rows=46 loops=3)
-- -> Parallel Seq Scan on gamedetail gd (cost=0.00..16589.40 rows=84 width=6) (actual time=2.122..64.080 rows=46 loops=3)
-- Filter: ((steals >= '5'::numeric) AND (startposition = 'C'::bpchar))
-- Rows Removed by Filter: 215176
-- -> Index Scan using player_pkey on player p (cost=0.28..0.89 rows=1 width=19) (actual time=0.007..0.007 rows=1 loops=137)
-- Index Cond: ((id)::text = (gd.idplayer)::text)
-- Planning Time: 0.988 ms
-- Execution Time: 81.023 ms
-- (11 rows)
--? 9 - Comment améliorer les performances de cette requête ? Tester et comparer.
CREATE INDEX idx3 ON GameDetail(startposition, steals);
EXPLAIN ANALYZE
SELECT p.id, p.name
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND gd.steals >= 5 AND gd.startposition = 'C';
-- QUERY PLAN
-- ---------------------------------------------------------------------------------------------------------------------------
-- Hash Join (cost=82.42..810.23 rows=201 width=19) (actual time=5.164..6.532 rows=137 loops=1)
-- Hash Cond: ((gd.idplayer)::text = (p.id)::text)
-- -> Bitmap Heap Scan on gamedetail gd (cost=6.49..733.77 rows=201 width=6) (actual time=0.648..1.910 rows=137 loops=1)
-- Recheck Cond: ((startposition = 'C'::bpchar) AND (steals >= '5'::numeric))
-- Heap Blocks: exact=135
-- -> Bitmap Index Scan on idx3 (cost=0.00..6.43 rows=201 width=0) (actual time=0.567..0.568 rows=137 loops=1)
-- Index Cond: ((startposition = 'C'::bpchar) AND (steals >= '5'::numeric))
-- -> Hash (cost=43.75..43.75 rows=2575 width=19) (actual time=4.471..4.471 rows=2575 loops=1)
-- Buckets: 4096 Batches: 1 Memory Usage: 165kB
-- -> Seq Scan on player p (cost=0.00..43.75 rows=2575 width=19) (actual time=0.027..2.996 rows=2575 loops=1)
-- Planning Time: 1.538 ms
-- Execution Time: 6.690 ms
-- (12 rows)
--? 10 - Supprimer tout les index précédents.
--? Pour s'aider : commande \di qui affiche tous les index de votre base.
--? (Remarquez quil existe plusieurs index dont le nom se termine par _pkey.
--? Ce sont des index créés automatiquement sur les clés primaires des tables.
--? Inutile de les supprimer.)
\di
DROP INDEX idx;
DROP INDEX idx2;
DROP INDEX idx3;
\di
--? 11 - Les deux requêtes ci-dessous calculent la même chose. Que font-elles?
SELECT t.nickname, t.city, count(*)
FROM Team t, Game g
WHERE (t.id = g.idHomeTeam AND g.homeTeamWins) OR (t.id = g.idVisitorTeam
AND NOT g.homeTeamWins)
GROUP BY t.nickname , t.city ORDER BY 3 DESC;
-- * Celle ci affiche le surnom, la ville de l'équipe ainsi que le nombre de match victorieux au total (exterieur ou non)
-- * De la table game et team puis koin la team soit en equipe maison ou externe au terrain (si maison, alors victorieuse (impossible en exterieur))
-- * Enfin, on ordonne le tout par nombre de match gagné
-- nickname | city | count
-- ---------------+---------------+-------
-- Spurs | San Antonio | 1166
-- Heat | Miami | 1037
-- Celtics | Boston | 1011
-- Mavericks | Dallas | 1002
-- Warriors | Golden State | 982
-- Rockets | Houston | 982
-- Nuggets | Denver | 968
-- Lakers | Los Angeles | 929
-- Jazz | Utah | 925
-- Thunder | Oklahoma City | 911
-- Pacers | Indiana | 905
-- Cavaliers | Cleveland | 899
-- Clippers | Los Angeles | 892
-- Raptors | Toronto | 884
-- Suns | Phoenix | 881
-- Bulls | Chicago | 866
-- Trail Blazers | Portland | 850
-- Grizzlies | Memphis | 850
-- Pistons | Detroit | 835
-- Bucks | Milwaukee | 816
-- Hawks | Atlanta | 804
-- Magic | Orlando | 761
-- 76ers | Philadelphia | 760
-- Pelicans | New Orleans | 759
-- Nets | Brooklyn | 750
-- Wizards | Washington | 736
-- Kings | Sacramento | 674
-- Knicks | New York | 657
-- Timberwolves | Minnesota | 654
-- Hornets | Charlotte | 621
-- (30 rows)
SELECT t.nickname, t.city, hw.nb+vw.nb
FROM Team t, (SELECT t.id, count(*) nb
FROM Team t, Game g
WHERE t.id = g.idHomeTeam AND g.homeTeamWins
GROUP BY t.id) hw,
(SELECT t.id, count(*) nb
FROM Team t, Game g
WHERE t.id = g.idVisitorTeam AND NOT g.homeTeamWins
GROUP BY t.id) vw
WHERE t.id = hw.id AND t.id = vw.id
ORDER BY 3 DESC;
-- * Pour celle ci, on affiche le surnom, la ville de l'équipe ainsi que son nombre de win maison + son nombre de win exterieur
-- * Depuis la table team et deux autres tables qui contiennent le nombre de win hom et le nombre de win exterieur
-- * On join la team à ses deux win
-- * Puis on le trie par nombre de win total.
-- nickname | city | ?column?
-- ---------------+---------------+----------
-- Spurs | San Antonio | 1166
-- Heat | Miami | 1037
-- Celtics | Boston | 1011
-- Mavericks | Dallas | 1002
-- Rockets | Houston | 982
-- Warriors | Golden State | 982
-- Nuggets | Denver | 968
-- Lakers | Los Angeles | 929
-- Jazz | Utah | 925
-- Thunder | Oklahoma City | 911
-- Pacers | Indiana | 905
-- Cavaliers | Cleveland | 899
-- Clippers | Los Angeles | 892
-- Raptors | Toronto | 884
-- Suns | Phoenix | 881
-- Bulls | Chicago | 866
-- Trail Blazers | Portland | 850
-- Grizzlies | Memphis | 850
-- Pistons | Detroit | 835
-- Bucks | Milwaukee | 816
-- Hawks | Atlanta | 804
-- Magic | Orlando | 761
-- 76ers | Philadelphia | 760
-- Pelicans | New Orleans | 759
-- Nets | Brooklyn | 750
-- Wizards | Washington | 736
-- Kings | Sacramento | 674
-- Knicks | New York | 657
-- Timberwolves | Minnesota | 654
-- Hornets | Charlotte | 621
-- (30 rows)
--? 12 - Sans les exécuter, laquelle de ces deux requêtes est la plus rapide selon vous ? Justifier.
-- * Selon moi, Je pense que la deuxième est meilleur car d'une part elle n'as pas de GROUP BY, ce qui devrait etre moins gourmand.
-- * D'autre part, elle calcule séparement le home du away ce qui, je pense, en indexant devrait etre plus rapide.
--? 13 - Vérifier votre réponse en affichant le temps dexécution de chaque requête.
EXPLAIN ANALYZE
SELECT t.nickname, t.city, count(*)
FROM Team t, Game g
WHERE (t.id = g.idHomeTeam AND g.homeTeamWins) OR (t.id = g.idVisitorTeam
AND NOT g.homeTeamWins)
GROUP BY t.nickname , t.city ORDER BY 3 DESC;
-- QUERY PLAN
-- ----------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Sort (cost=65828.12..65828.60 rows=190 width=164) (actual time=159.839..159.842 rows=30 loops=1)
-- Sort Key: (count(*)) DESC
-- Sort Method: quicksort Memory: 27kB
-- -> HashAggregate (cost=65819.03..65820.93 rows=190 width=164) (actual time=159.815..159.820 rows=30 loops=1)
-- Group Key: t.nickname, t.city
-- Batches: 1 Memory Usage: 40kB
-- -> Nested Loop (cost=0.00..65626.02 rows=25735 width=156) (actual time=0.072..152.901 rows=25767 loops=1)
-- Join Filter: ((((t.id)::text = (g.idhometeam)::text) AND g.hometeamwins) OR (((t.id)::text = (g.idvisitorteam)::text) AND (NOT g.hometeamwins)))
-- Rows Removed by Join Filter: 747243
-- -> Seq Scan on game g (cost=0.00..699.67 rows=19523 width=23) (actual time=0.026..5.395 rows=25767 loops=1)
-- Filter: (hometeamwins OR (NOT hometeamwins))
-- -> Materialize (cost=0.00..12.85 rows=190 width=194) (actual time=0.000..0.001 rows=30 loops=25767)
-- -> Seq Scan on team t (cost=0.00..11.90 rows=190 width=194) (actual time=0.008..0.016 rows=30 loops=1)
-- Planning Time: 0.486 ms
-- Execution Time: 159.978 ms
-- (15 rows)
-- * Pour cette premiere question, cela bloque bien à l'endroit que je pensais
-- * En indexant, on devrait surement avoir de meilleures résultats.
EXPLAIN ANALYZE
SELECT t.nickname, t.city, hw.nb+vw.nb
FROM Team t, (SELECT t.id, count(*) nb
FROM Team t, Game g
WHERE t.id = g.idHomeTeam AND g.homeTeamWins
GROUP BY t.id) hw,
(SELECT t.id, count(*) nb
FROM Team t, Game g
WHERE t.id = g.idVisitorTeam AND NOT g.homeTeamWins
GROUP BY t.id) vw
WHERE t.id = hw.id AND t.id = vw.id
ORDER BY 3 DESC;
-- QUERY PLAN
-- -------------------------------------------------------------------------------------------------------------------------------------------------------
-- Sort (cost=1658.81..1659.29 rows=190 width=164) (actual time=34.733..34.742 rows=30 loops=1)
-- Sort Key: ((hw.nb + vw.nb)) DESC
-- Sort Method: quicksort Memory: 27kB
-- -> Hash Join (cost=1638.23..1651.62 rows=190 width=164) (actual time=34.660..34.698 rows=30 loops=1)
-- Hash Cond: ((t.id)::text = (vw.id)::text)
-- -> Hash Join (cost=836.44..848.85 rows=190 width=240) (actual time=19.458..19.477 rows=30 loops=1)
-- Hash Cond: ((t.id)::text = (hw.id)::text)
-- -> Seq Scan on team t (cost=0.00..11.90 rows=190 width=194) (actual time=0.030..0.034 rows=30 loops=1)
-- -> Hash (cost=834.06..834.06 rows=190 width=46) (actual time=19.374..19.376 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Subquery Scan on hw (cost=830.26..834.06 rows=190 width=46) (actual time=19.302..19.317 rows=30 loops=1)
-- -> HashAggregate (cost=830.26..832.16 rows=190 width=46) (actual time=19.300..19.308 rows=30 loops=1)
-- Group Key: t_1.id
-- Batches: 1 Memory Usage: 40kB
-- -> Hash Join (cost=14.28..754.57 rows=15138 width=38) (actual time=0.048..13.843 rows=15138 loops=1)
-- Hash Cond: ((g.idhometeam)::text = (t_1.id)::text)
-- -> Seq Scan on game g (cost=0.00..699.67 rows=15138 width=11) (actual time=0.009..7.778 rows=15138 loops=1)
-- Filter: hometeamwins
-- Rows Removed by Filter: 10629
-- -> Hash (cost=11.90..11.90 rows=190 width=38) (actual time=0.024..0.025 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Seq Scan on team t_1 (cost=0.00..11.90 rows=190 width=38) (actual time=0.004..0.010 rows=30 loops=1)
-- -> Hash (cost=799.41..799.41 rows=190 width=46) (actual time=15.177..15.180 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Subquery Scan on vw (cost=795.61..799.41 rows=190 width=46) (actual time=15.132..15.148 rows=30 loops=1)
-- -> HashAggregate (cost=795.61..797.51 rows=190 width=46) (actual time=15.128..15.139 rows=30 loops=1)
-- Group Key: t_2.id
-- Batches: 1 Memory Usage: 40kB
-- -> Hash Join (cost=14.28..742.47 rows=10629 width=38) (actual time=0.110..11.306 rows=10629 loops=1)
-- Hash Cond: ((g_1.idvisitorteam)::text = (t_2.id)::text)
-- -> Seq Scan on game g_1 (cost=0.00..699.67 rows=10629 width=11) (actual time=0.037..7.024 rows=10629 loops=1)
-- Filter: (NOT hometeamwins)
-- Rows Removed by Filter: 15138
-- -> Hash (cost=11.90..11.90 rows=190 width=38) (actual time=0.044..0.045 rows=30 loops=1)
-- Buckets: 1024 Batches: 1 Memory Usage: 10kB
-- -> Seq Scan on team t_2 (cost=0.00..11.90 rows=190 width=38) (actual time=0.012..0.020 rows=30 loops=1)
-- Planning Time: 0.826 ms
-- Execution Time: 35.012 ms
-- (38 rows)
-- * La différence est choquante, je ne m'attendais pas à ca mais je n'étais pas du tout sur la bonne raison.
-- * On dirait que c'est grace à la jointure des id que l'on gagne bcp de temps car comme on l'a vu précédemment,
-- * les PK sont déjà indéxé de base ce qui améliore l'éxécution de bcp. Mais ce point serait bien à revoir pour moi.
--? 14 - Lister les joueurs ayant marqué plus de 40 points dans un match, avec le nombre de matchs
--? pour lesquels le joueur a réussi cette performance.
SELECT p.id, p.name, count(*)
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND gd.points >= 40
GROUP BY p.id, p.name
ORDER BY 3 DESC;
-- * Meme structure que la première donc devrait etre moins opti
-- id | name | count
-- ---------+-------------------------+-------
-- 201935 | James Harden | 112
-- 977 | Kobe Bryant | 106
-- 2544 | LeBron James | 97
-- 201142 | Kevin Durant | 73
-- 201939 | Stephen Curry | 64
-- 201566 | Russell Westbrook | 57
-- 203081 | Damian Lillard | 44
-- 2546 | Carmelo Anthony | 41
-- 2548 | Dwyane Wade | 41
-- 203076 | Anthony Davis | 38
-- 947 | Allen Iverson | 32
-- 203507 | Giannis Antetokounmpo | 32
-- 203078 | Bradley Beal | 30
-- 2240 | Gilbert Arenas | 29
-- 202681 | Kyrie Irving | 27
-- 203954 | Joel Embiid | 24
-- 1503 | Tracy McGrady | 24
-- 1629027 | Trae Young | 23
-- 2405 | Amar'e Stoudemire | 22
-- 1717 | Dirk Nowitzki | 22
-- 1713 | Vince Carter | 22
-- 1626164 | Devin Booker | 20
-- 1629029 | Luka Doncic | 20
-- 202331 | Paul George | 19
-- 202689 | Kemba Walker | 19
-- 201942 | DeMar DeRozan | 16
-- 203897 | Zach LaVine | 15
-- 202691 | Klay Thompson | 14
-- 1628369 | Jayson Tatum | 14
-- 1628378 | Donovan Mitchell | 13
-- 202326 | DeMarcus Cousins | 13
-- 203999 | Nikola Jokic | 12
-- 2072 | Michael Redd | 12
-- 101108 | Chris Paul | 11
-- 200746 | LaMarcus Aldridge | 11
-- 201933 | Blake Griffin | 11
-- 201567 | Kevin Love | 11
-- 2547 | Chris Bosh | 10
-- 203468 | CJ McCollum | 10
-- 101145 | Monta Ellis | 10
-- 202695 | Kawhi Leonard | 10
-- 1626157 | Karl-Anthony Towns | 10
-- 202710 | Jimmy Butler | 10
-- 2037 | Jamal Crawford | 9
--? 15 - Quel index pourrait permettre daméliorer le temps dexécution de la requête ? Justifier votre réponse.
EXPLAIN ANALYZE
SELECT p.id, p.name, count(*)
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND gd.points >= 40
GROUP BY p.id, p.name
ORDER BY 3 DESC;
-- QUERY PLAN
-- --------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Sort (cost=17293.10..17297.02 rows=1570 width=27) (actual time=166.819..168.162 rows=196 loops=1)
-- Sort Key: (count(*)) DESC
-- Sort Method: quicksort Memory: 40kB
-- -> Finalize GroupAggregate (cost=17025.10..17209.76 rows=1570 width=27) (actual time=166.127..168.110 rows=196 loops=1)
-- Group Key: p.id
-- -> Gather Merge (cost=17025.10..17187.52 rows=1308 width=27) (actual time=166.117..168.026 rows=376 loops=1)
-- Workers Planned: 2
-- Workers Launched: 2
-- -> Partial GroupAggregate (cost=16025.07..16036.52 rows=654 width=27) (actual time=152.688..152.792 rows=125 loops=3)
-- Group Key: p.id
-- -> Sort (cost=16025.07..16026.71 rows=654 width=19) (actual time=152.674..152.698 rows=546 loops=3)
-- Sort Key: p.id
-- Sort Method: quicksort Memory: 71kB
-- Worker 0: Sort Method: quicksort Memory: 61kB
-- Worker 1: Sort Method: quicksort Memory: 64kB
-- -> Hash Join (cost=75.94..15994.49 rows=654 width=19) (actual time=2.969..152.075 rows=546 loops=3)
-- Hash Cond: ((gd.idplayer)::text = (p.id)::text)
-- -> Parallel Seq Scan on gamedetail gd (cost=0.00..15916.83 rows=654 width=6) (actual time=1.040..149.731 rows=546 loops=3)
-- Filter: (points >= '40'::numeric)
-- Rows Removed by Filter: 214675
-- -> Hash (cost=43.75..43.75 rows=2575 width=19) (actual time=1.770..1.771 rows=2575 loops=3)
-- Buckets: 4096 Batches: 1 Memory Usage: 165kB
-- -> Seq Scan on player p (cost=0.00..43.75 rows=2575 width=19) (actual time=0.051..0.730 rows=2575 loops=3)
-- Planning Time: 1.028 ms
-- Execution Time: 168.314 ms
-- (25 rows)
-- ! DONC :
CREATE INDEX idx ON GameDetail(points);
-- QUERY PLAN
-- --------------------------------------------------------------------------------------------------------------------------------------------
-- Sort (cost=4622.02..4625.93 rows=1566 width=27) (actual time=17.991..18.038 rows=196 loops=1)
-- Sort Key: (count(*)) DESC
-- Sort Method: quicksort Memory: 40kB
-- -> HashAggregate (cost=4523.26..4538.92 rows=1566 width=27) (actual time=17.787..17.860 rows=196 loops=1)
-- Group Key: p.id
-- Batches: 1 Memory Usage: 97kB
-- -> Hash Join (cost=108.50..4515.43 rows=1566 width=19) (actual time=2.438..16.954 rows=1639 loops=1)
-- Hash Cond: ((gd.idplayer)::text = (p.id)::text)
-- -> Bitmap Heap Scan on gamedetail gd (cost=32.56..4435.37 rows=1566 width=6) (actual time=0.956..14.274 rows=1639 loops=1)
-- Recheck Cond: (points >= '40'::numeric)
-- Heap Blocks: exact=1504
-- -> Bitmap Index Scan on idx (cost=0.00..32.17 rows=1566 width=0) (actual time=0.633..0.634 rows=1639 loops=1)
-- Index Cond: (points >= '40'::numeric)
-- -> Hash (cost=43.75..43.75 rows=2575 width=19) (actual time=1.456..1.458 rows=2575 loops=1)
-- Buckets: 4096 Batches: 1 Memory Usage: 165kB
-- -> Seq Scan on player p (cost=0.00..43.75 rows=2575 width=19) (actual time=0.022..0.606 rows=2575 loops=1)
-- Planning Time: 2.630 ms
-- Execution Time: 18.270 ms
-- (18 rows)
--? 16 - Lister les joueurs ayant réalisé un total dassists et de vols supérieur à 22 pendant un match.
SELECT p.id, p.name, assists, blockedShots
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND assists > 22 AND blockedShots > 22;
-- id | name | assists | blockedshots
-- ----+------+---------+--------------
-- (0 rows)
-- ! Ou ??? :
SELECT p.id, p.name, assists, blockedShots
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND (assists + blockedShots) > 22;
-- id | name | assists | blockedshots
-- --------+-------------------+---------+--------------
-- 201566 | Russell Westbrook | 24 | 1
-- 201196 | Ramon Sessions | 24 | 1
-- 959 | Steve Nash | 23 | 1
-- 200765 | Rajon Rondo | 23 | 1
-- 200765 | Rajon Rondo | 24 | 0
-- 201566 | Russell Westbrook | 24 | 0
-- 200765 | Rajon Rondo | 25 | 0
-- 201566 | Russell Westbrook | 22 | 1
-- (8 rows)
--? 17 - Quel index pourrait permettre daméliorer le temps dexécution de la requête ? Justifier votre
--? réponse.
EXPLAIN ANALYZE
SELECT p.id, p.name, gd.assists, gd.blockedShots
FROM Player p, GameDetail gd
WHERE p.id = gd.idPlayer AND (gd.assists + gd.blockedShots) > 22;
-- QUERY PLAN
-- --------------------------------------------------------------------------------------------------------------------------
-- Hash Join (cost=75.94..22880.79 rows=215221 width=26) (actual time=19.979..161.473 rows=8 loops=1)
-- Hash Cond: ((gd.idplayer)::text = (p.id)::text)
-- -> Seq Scan on gamedetail gd (cost=0.00..22238.96 rows=215221 width=13) (actual time=18.738..160.218 rows=8 loops=1)
-- Filter: ((assists + blockedshots) > '22'::numeric)
-- Rows Removed by Filter: 645656
-- -> Hash (cost=43.75..43.75 rows=2575 width=19) (actual time=1.201..1.202 rows=2575 loops=1)
-- Buckets: 4096 Batches: 1 Memory Usage: 165kB
-- -> Seq Scan on player p (cost=0.00..43.75 rows=2575 width=19) (actual time=0.023..0.512 rows=2575 loops=1)
-- Planning Time: 1.002 ms
-- Execution Time: 161.535 ms
-- (10 rows)
--! CREATE INDEX idx2 ON GameDetail(assists, blockedshots); PAS OK
-- * JSP la

Binary file not shown.
Loading…
Cancel
Save