Unofficial Chess Federation ♕
Introduction
- Écrivez des requêtes jolies !
- À la fin du TP, exportez ou copiez vos requêtes dans un fichier de votre VM ou machine personnelle
1 Lancement des services
Pour plus de détails, allez dans l’onglet Datalab.
-
- ouvrez ce service
- vérifiez que vous êtes connectés à la base de données PostgreSQL
2 Les données
2.1 Chargez les données
-
- Cliquez sur la petite icone sous les triangles oranges qui ressemble à 📜
- raccourci (ALT + X)
2.2 Description des tables
| Catégorie | Description |
|---|---|
| Joueuse | Liste des joueuses |
| Titre | Liste des titres, certains attribués aux fortes joueuses |
| Club | Liste des clubs |
| Partie | Partie entre 2 joueuses, soit libre, soit dans le cadre d’un tournoi |
| Résultat_partie | Différents résultats possibles dans une partie (par exemple : victoire des blancs, match nul, etc.) |
| Ouverture | Désignation de l’ouverture (comment débute une partie) |
| Tournoi | Liste des tournois |
| Cadence | Rythme de jeu lors d’un tournoi (blitz, rapide, lent) |
2.3 Modèle de données
Dans le modèle de données, certaines tables sont reliées 2 fois entre elles :
- joueuse et partie : car lors d’une partie une joueuse a les blancs et l’autre, les noirs
- joueuse et club :
- id_club est une clé étrangère dans la table joueuse car une joueuse est membre d’un seul club
- id_presidente est une clé étrangère de la table club référençant l’id_joueuse de la présidente
Quelques remarques sur ce schéma :
- 🔑 clé primaire
#clé étrangère- NN : NOT NULL
2.4 Notation relationnelle
Les tables sont les suivantes :
- joueuse(id_joueuse, code_titre, nom, prenom, elo, date_naissance, #id_club, arbitre)
- titre(code, nom, description)
- club(id_club, nom, ville, #id_presidente)
- partie(id_partie, #id_blanc, #id_noir, date_partie, #id_resultat, #id_ouverture, #id_tournoi)
- resultat_partie(id_resultat, resultat, description)
- ouverture(id_ouverture, eco, nom, coups)
- tournoi(id_tournoi, nom, ville, date_debut, date_fin, #id_cadence, nb_rondes, nb_participantes, #id_arbitre)
- cadence(id_cadence, nom, description)
3 Recherche des irrégularités
Il paraîtrait que certaines joueuses aient truquées leurs classements elo. Vérifiez et corrigez cela :
-
- Notez leurs id_joueuse
Une autre erreur concernerait les dates de naissances des joueuses
Passons maintenant à la table des parties. À votre avis, est-ce normal de jouer des parties contre soi-même ?
4 Élection des présidentes
-
- affichez le nom du club, ainsi que tout le contenu de la table joueuse
-
- en cas d’égalité, prenez ensuite le plus petit id_joueuse
5 Quelques statistiques
-
- affichez le nom du tournoi
- incluez les parties jouées hors tournoi
- Commencez par exemple par calculer le nombre de victoires des blancs
- Divisez par le bon nombre
- Pour avoir un float, vous pouvez multiplier par 1.0
- Utilisez ROUND() pour arrondir à 2 chiffres significatifs
Le but des questions suivantes va être d’afficher le nombre de parties jouées en tournoi et hors tournoi.
Le résultat doit être l’un des deux ci-dessous :
| tournoi | nb_parties |
|---|---|
| false | 10000 |
| true | 3610 |
| nb_parties_en_tournoi | nb_parties_hors_tournoi |
|---|---|
| 3610 | 10000 |
Affichez ce résultat avec une requête utilisant :
Jetons maintenant un oeil aux ouvertures qui permettent de gagner plus souvent.
En début de partie, le nombre de coups possibles et corrects reste assez limité. Les différentes possibilités de commencer une partie sont catégorisées et appelées Ouvertures.
Vient ensuite le milieu de jeu lorsque toutes les pièces sont développées.
Et enfin (si personne ne s’est pris un échec et mat) la finale, i.e. lorsque les Dames ont été échangées et qu’il reste peu de pièces.
-
- Trouvez et supprimez cette ouverture
-
- nombre de parties jouées
- taux de victoire des blancs
- taux de victoire des noirs
- taux de matchs nuls
6 Afficher les résultats de parties
Les résultats de parties sont généralement affichés sous ce format :
| Blancs | Rés | Noirs | ||
|---|---|---|---|---|
| PRZYMUSINSKI Nicolas | 2043 | 0 - 1 | f GREGOIRE Sylvain | 2268 |
| MEYNARD Thibault | 2256 | 1 - 0 | ZERMICHE Cherif | 2035 |
| HOUARD Yannick | 2010 | X - X | PEREZ Flavio | 2230 |
| COULON Guillaume | 2001 | 0 - 1 | JOLLY Jean-Francois | 2211 |
| FISCHER Marc | 2185 | X - X | DENEUVILLE Ludovic | 2003 |
| MATHIS Julien | 1951 | 0 - 1 | PIERONI Guillaume | 2170 |
| BOIZANTE Yvain | 2148 | X - X | SAEZ Nicolas | 1998 |
7 Gagnantes des tournois
Via la table partie, il est possible de retrouver quelle joueuse a participé à quel tournoi.
Cependant ce n’est pas très intuitif, ni pratique.
Nous allons donc commencer par créer une vue des participantes
-
- en y insérant les données de la dernière requête
Cependant un problème se pose : une seule ligne de la partie contient le nombre de points marqués de 2 joueuses.
| id_partie | id_blanc | id_noir | resultat |
|---|---|---|---|
| 1 | 11 | 22 | 1 - 0 |
| 2 | 123 | 99 | X - X |
Pour calculer les points de chaque joueuse, ce serait plus pratique de dupliquer chaque ligne pour avoir :
| id_partie | id_joueuse | score |
|---|---|---|
| 1 | 11 | 1 |
| 1 | 22 | 0 |
| 2 | 123 | 0.5 |
| 2 | 99 | 0.5 |
-
- id_tournoi
- le elo de l’adversaire
- Vous pouvez utiliser une structure CASE WHEN THEN
SELECT <?>,
CASE
WHEN <?> THEN <?>
WHEN <?> THEN <?>
ELSE <?>
END AS score
FROM <?>Vous remarquez qu’il y a des égalités au nombre de points.
-
- Plus la joueuse a affronté d’autres joueuses fortes, mieux elle sera classée
Une petite requête basique pour vérifier vos résultats :
WITH resultat_score AS (
SELECT rp.*,
CASE
WHEN rp.resultat IN ('1 - 0', '1 - F') THEN 1
WHEN rp.resultat = 'X - X' THEN 0.5
ELSE 0
END AS score_blanc,
CASE
WHEN rp.resultat IN ('0 - 1', 'F - 1') THEN 1
WHEN rp.resultat = 'X - X' THEN 0.5
ELSE 0
END AS score_noir
FROM echecs.resultat_partie rp
),
partie_score AS (
SELECT p.id_partie,
p.id_tournoi,
UNNEST(ARRAY[id_blanc, id_noir]) AS id_joueuse,
UNNEST(ARRAY[score_blanc, score_noir]) AS score,
UNNEST(ARRAY[jn.elo, jb.elo]) AS elo_adversaire
FROM echecs.partie p
JOIN resultat_score USING(id_resultat)
JOIN echecs.joueuse jb ON (jb.id_joueuse = p.id_blanc)
JOIN echecs.joueuse jn ON (jn.id_joueuse = p.id_noir)
)
SELECT CONCAT_WS(' ', LOWER(j.code_titre), j.nom, j.prenom) AS joueuse,
j.elo,
SUM(ps.score) AS points,
ROUND(AVG(ps.elo_adversaire)) AS moyenne_elo_adversaire
FROM echecs.joueuse j
JOIN partie_score ps USING(id_joueuse)
JOIN echecs.tournoi t USING(id_tournoi)
WHERE t.nom = 'Open de Guingamp'
GROUP BY j.id_joueuse,
joueuse,
j.elo
ORDER BY points DESC,
moyenne_elo_adversaire DESC;-
- incluez le nom du tournoi, de la joueuse, son nombre de points, la moyenne elo des adversaire
- calculez son classement dans le tournoi (💡 voir RANK OVER PARTITION BY)
8 Qui est la meilleure ?
Choisissez une joueuse, par exemple Judith POLGAR
-
- classez par ratio de points par partie déscroissant
Arrêtez vos services
C’est la fin du TP, vous pouvez maintenant sauvegarder votre travail et libérer les ressources réservées :