TP 12 : bases de données

Cliquez sur cette invitation pour récupérer le repository du TP.


Présentation


On va utiliser python dans ce tp pout accéder aux bases de données, mais de manière la plus transparente possible.


Un problème de mis-à-jour récent impose d’obliger Colab à passer à la dernière version du module permettant d’utiliser les commandes sql magiques.
La première commande exécutée de votre notebook devra donc être (ajoutez la commande dans une nouvelle cellule au début du notebook) :

%%capture
!pip install ipython-sql==0.5.0

Commençons par cloner le repository Github source dans l’instance Colab.

!git clone https://github.com/Info-TSI-Vieljeux/s3-tp12

Puis, chargeons une extension ipython permettant de se connecter à une base de données et d’interagir avec en SQL.

%load_ext sql

Connectons-nous à la base Population.db issue de données de l’INSEE pour pouvoir tester les exemples du cours et pour quelques questions.

%sql sqlite:///s3-tp12/Population.db

Dorénavent, il suffit de débuter chaque cellule par la commande magique %%sql et d’écrire en dessous vos requêtes SQL. En ajoutant resultats << à la ligne introductive, on stocke le résultat de la requête dans la variable resultats.

%%sql resultats <<

SELECT *
FROM Communes
LIMIT 10;

sqlite:///s3-tp12/F1.db
* sqlite:///s3-tp12/Population.db
Done.
Returning data to local variable resultats

Pour afficher les résultats, il suffit d’exécuter resultats :

resultats
CODREG CODDEP CODCOM COM POP
84 01 1 L'Abergement-Clémenciat 798
84 01 2 L'Abergement-de-Varey 257
84 01 4 Ambérieu-en-Bugey 14514
84 01 5 Ambérieux-en-Dombes 1776
84 01 6 Ambléon 118
84 01 7 Ambronay 2915
84 01 8 Ambutrix 777
84 01 9 Andert-et-Condon 335
84 01 10 Anglefort 1122
84 01 11 Apremont 379

Écrivez une requête affichant le numéro des départements contenant au moins une commune de plus de $100\,000$ habitants ainsi que le nom de ces communes.

Correction (cliquer pour afficher)
SELECT CODDEP, COM
FROM Communes
WHERE POP > 100000;
CODDEP COM
06 Nice
13 Aix-en-Provence
14 Caen
21 Dijon
25 Besançon
29 Brest
30 Nîmes
31 Toulouse
33 Bordeaux
34 Montpellier
35 Rennes
37 Tours
38 Grenoble
42 Saint-Étienne
44 Nantes
45 Orléans
49 Angers
51 Reims
54 Nancy
57 Metz
59 Lille
63 Clermont-Ferrand
66 Perpignan
67 Strasbourg
68 Mulhouse
69 Villeurbanne
69 Lyon 3e Arrondissement
72 Le Mans
74 Annecy
75 Paris 11e Arrondissement
75 Paris 12e Arrondissement
75 Paris 13e Arrondissement
75 Paris 14e Arrondissement
75 Paris 15e Arrondissement
75 Paris 16e Arrondissement
75 Paris 17e Arrondissement
75 Paris 18e Arrondissement
75 Paris 19e Arrondissement
75 Paris 20e Arrondissement
76 Le Havre
76 Rouen
80 Amiens
83 Toulon
87 Limoges
92 Boulogne-Billancourt
93 Montreuil
93 Saint-Denis
95 Argenteuil
974 Saint-Denis
974 Saint-Paul

Écrivez maintenant une requête permettant d’obtenir la liste des noms de chaque département associés au nombre de communes qu’ils contiennent, en triant de manière décroissante selon le nombre de communes par département.

Correction (cliquer pour afficher)
SELECT NBCOM,DEP
FROM Departements
ORDER BY NBCOM DESC;
NBCOM DEP
890 Pas-de-Calais
800 Aisne
772 Somme
725 Moselle
708 Seine-Maritime
698 Côte-d'Or
679 Oise
648 Nord
613 Marne
591 Meurthe-et-Moselle
586 Haute-Garonne
585 Eure
573 Doubs
565 Saône-et-Loire
546 Pyrénées-Atlantiques
539 Haute-Saône
535 Gironde
528 Calvados
514 Bas-Rhin
512 Isère
507 Seine-et-Marne
507 Vosges
505 Dordogne
499 Meuse
494 Jura
469 Hautes-Pyrénées
464 Puy-de-Dôme
463 Charente-Maritime
461 Gers
449 Ardennes
446 Manche
433 Aude
431 Aube
426 Haute-Marne
423 Yonne
393 Ain
385 Orne
366 Haut-Rhin
365 Charente
365 Eure-et-Loir
364 Drôme
354 Sarthe
351 Gard
348 Côtes-d'Armor
342 Hérault
335 Ardèche
333 Ille-et-Vilaine
327 Ariège
327 Landes
325 Loiret
323 Loire
319 Lot-et-Garonne
317 Allier
314 Tarn
313 Lot
309 Nièvre
287 Cher
285 Aveyron
280 Corrèze
279 Haute-Savoie
277 Finistère
273 Savoie
272 Indre-et-Loire
267 Loir-et-Cher
267 Rhône
266 Vienne
259 Yvelines
258 Vendée
257 Haute-Loire
256 Creuse
256 Deux-Sèvres
250 Morbihan
246 Cantal
241 Indre
240 Mayenne
236 Haute-Corse
226 Pyrénées-Orientales
207 Loire-Atlantique
198 Alpes-de-Haute-Provence
195 Tarn-et-Garonne
195 Haute-Vienne
194 Essonne
184 Val-d'Oise
177 Maine-et-Loire
163 Alpes-Maritimes
162 Hautes-Alpes
153 Var
152 Lozère
151 Vaucluse
124 Corse-du-Sud
119 Bouches-du-Rhône
101 Territoire de Belfort
47 Val-de-Marne
40 Seine-Saint-Denis
36 Hauts-de-Seine
34 Martinique
32 Guadeloupe
24 La Réunion
22 Guyane
1 Paris

Écrivez ensuite une requête permettant d’obtenir la liste des noms de communes donnés plusieurs fois associés au nombre de fois où ils sont répétés, nombre que l’on rebaptisera NB_REDOND. La liste ne devra contenir que les noms donnés au moins 10 fois.

Correction (cliquer pour afficher)
SELECT COM,COUNT(*) AS NB_REDOND
FROM Communes
GROUP BY COM
HAVING NB_REDOND >= 10;
COM NB_REDOND
Beaulieu 10
Saint-Aubin 10
Saint-Sauveur 11
Sainte-Colombe 12

Écrivez une requête donnant le nom d’une ville, ici ‘La Rochelle’, le nom du département auquel elle appartient, et le nom de la région auquelle elle appartient.

Correction (cliquer pour afficher)
SELECT COM, DEP, REG
FROM Communes
JOIN Regions ON Communes.CODREG = Regions.CODREG
JOIN Departements ON Communes.CODDEP = Departements.CODDEP
WHERE COM = "La Rochelle";
COM DEP REG
La Rochelle Charente-Maritime Nouvelle-Aquitaine
La Rochelle Haute-Saône Bourgogne-Franche-Comté

Écrivez enfin une requête donnant le nom du département Charente-Maritime, sa population, le nombre de communes qu’il contient, le nom de la commune la plus peuplée et sa population ainsi que le nom de la commune la moins peuplée et sa population.

Correction (cliquer pour afficher)
SELECT DEP, Departements.POP, Departements.NBCOM, MAXCOM, MAXPOP, MINCOM, MINPOP
FROM ((SELECT CODDEP, COM AS MAXCOM, MAX(POP) AS MAXPOP  
       FROM Communes
       GROUP BY CODDEP) AS MAXOU
       JOIN (SELECT CODDEP, COM AS MINCOM, MIN(POP) AS MINPOP  
             FROM Communes
             GROUP BY CODDEP) AS MINOU 
       ON MINOU.CODDEP = MAXOU.CODDEP) AS Autojointure
JOIN Departements ON Autojointure.CODDEP = Departements.CODDEP
WHERE DEP = "Charente-Maritime";
DEP POP NBCOM MAXCOM MAXPOP MINCOM MINPOP
Charente-Maritime 667287 463 La Rochelle 79333 Lussac 47

On construit généralement des grosses requêtes comme celle-ci bloc par bloc qu'on joint ensuite ensemble.
Regardons par exemple à quoi ressemble la table intermédiaire Autojointure (qui a été construite, comme son nom l'indique, par autojointure).
SELECT Autojointure.CODDEP, MAXCOM, MAXPOP, MINCOM, MINPOP
FROM
((SELECT CODDEP, COM AS MAXCOM, MAX(POP) AS MAXPOP  
  FROM Communes
  GROUP BY CODDEP) AS MAXOU
  JOIN (SELECT CODDEP, COM AS MINCOM, MIN(POP) AS MINPOP  
        FROM Communes
        GROUP BY CODDEP) AS MINOU 
  ON MINOU.CODDEP = MAXOU.CODDEP) AS Autojointure
CODDEP MAXCOM MAXPOP MINCOM MINPOP
01 Bourg-en-Bresse 42853 Armix 31
02 Saint-Quentin 54851 Tannières 17
03 Montluçon 35431 Saint-Éloy-d'Allier 38
04 Manosque 23197 Majastres 4
05 Gap 42176 La Haute-Beaume 8
06 Nice 345528 Auvare 33
07 Annonay 16920 Lafarre 39
08 Charleville-Mézières 47526 Le Mont-Dieu 15
09 Pamiers 16137 Senconac 13
10 Troyes 63087 Ortillon 24
11 Narbonne 56700 Fontanès-de-Sault 5
12 Rodez 26410 Arnac-sur-Dourdou 37
13 Aix-en-Provence 148336 Saint-Antonin-sur-Bayon 127
14 Caen 108404 Rapilly 48
15 Aurillac 26876 Valjouze 23
16 Angoulême 43290 Saint-Sulpice-de-Ruffec 31
17 La Rochelle 79333 Lussac 47
18 Bourges 66606 Saint-Céols 13
19 Brive-la-Gaillarde 47615 Toy-Viam 38
21 Dijon 161380 Les Goulles 9
22 Saint-Brieuc 45099 Loc-Envel 70
23 Guéret 13371 Beissat 25
24 Périgueux 31476 Faurilles 36
25 Besançon 121144 Châtillon-sur-Lison 8
26 Valence 66149 Rochefourchat 1
27 Évreux 47574 Vieux-Port 48
28 Chartres 39698 Morainville 19
29 Brest 142555 Trégarvan 120
2A Ajaccio 72228 Mela 30
2B Bastia 49198 Érone 12
30 Nîmes 150786 Revens 20
31 Toulouse 498596 Bourg-d'Oueil 5
32 Auch 23276 Roquepine 35
33 Bordeaux 264257 Bossugan 38
34 Montpellier 298933 Romiguières 23
35 Rennes 224655 Bléruais 108
36 Châteauroux 44662 Saint-Médard 52
37 Tours 139843 Couziers 111
38 Grenoble 160441 Oulles 6
39 Dole 24604 Mérona 7
40 Mont-de-Marsan 31220 Arx 49
41 Blois 47418 La Madeleine-Villefrouin 31
42 Saint-Étienne 175792 La Chambonie 40
43 Le Puy-en-Velay 20096 Arlet 23
44 Nantes 323975 Juigné-des-Moutiers 335
45 Orléans 118632 Feins-en-Gâtinais 34
46 Cahors 20877 Labastide-du-Haut-Mont 51
47 Agen 33464 Boussès 36
48 Mende 13147 Sainte-Eulalie 38
49 Angers 158930 La Lande-Chasles 123
50 Cherbourg-en-Cotentin 80912 Taillepied 18
51 Reims 184114 Rouvroy-Ripont 4
52 Saint-Dizier 23427 Charmes-en-l'Angle 7
53 Laval 52370 Rennes-en-Grenouilles 105
54 Nancy 106504 Leménil-Mitry 3
55 Verdun 17906 Beaumont-en-Verdunois 0
56 Lorient 58732 Hœdic 100
57 Metz 120335 Molring 5
58 Nevers 34069 Moissy-Moulinot 18
59 Lille 236400 Dehéries 39
60 Beauvais 58520 Gouy-les-Groseillers 25
61 Alençon 26622 Le Ménil-Vicomte 23
62 Calais 73134 Guinecourt 16
63 Clermont-Ferrand 150596 La Godivelle 16
64 Pau 77070 Aubous 45
65 Tarbes 43821 Ourdon 11
66 Perpignan 120771 Sansa 19
67 Strasbourg 290106 Blancherupt 34
68 Mulhouse 109531 Lucelle 33
69 Villeurbanne 153294 Vernay 105
70 Vesoul 15663 Ranzevelle 16
71 Chalon-sur-Saône 46577 Chérizet 20
72 Le Mans 146703 Nauvay 12
73 Chambéry 60478 Champ-Laurent 34
74 Annecy 134101 Novel 51
75 Paris 15e Arrondissement 232668 Paris 1er Arrondissement 16055
76 Le Havre 170120 Le Mesnil-Durdent 20
77 Meaux 56229 Montenils 25
78 Versailles 86846 Le Tartre-Gaudran 37
79 Niort 61027 Les Groseillers 57
80 Amiens 137380 Épécamps 5
81 Albi 50625 Senaux 34
82 Montauban 62832 Goas 39
83 Toulon 180641 Vérignon 9
84 Avignon 92821 Lagarde-d'Apt 33
85 La Roche-sur-Yon 58103 Marillet 124
86 Poitiers 91487 Lauthiers 70
87 Limoges 133136 Surdoux 47
88 Épinal 33706 Maroncourt 7
89 Auxerre 35554 Bois-d'Arcy 24
90 Belfort 47242 Lamadeleine-Val-des-Anges 45
91 Évry-Courcouronnes 67317 Chatignonville 69
92 Boulogne-Billancourt 122825 Marnes-la-Coquette 1835
93 Saint-Denis 113766 Coubron 4963
94 Vitry-sur-Seine 95969 Périgny 2712
95 Argenteuil 111595 Charmont 36
971 Les Abymes 54027 Terre-de-Bas 999
972 Fort-de-France 77410 Grand'Rivière 621
973 Cayenne 65878 Saül 159
974 Saint-Denis 155302 Saint-Philippe 5264

Changeons maintenant de base de données pour celle qui a eu les honneurs de l’épreuve Centrale 2022.
Vous trouverez ci-dessous deux extraits du sujet : d’abord l’introduction générale de l’épreuve puis la présentation de la base.

Petite modification sur la base :

  • to_temps est en ms dans la base qu’on va utiliser.
  • gp_date est de type TEXT (chaîne de caractères). Ex : 2009-03-29.

Les questions qui suivent sont adaptées du sujet 2022.

Pourquoi avoir utilisé la colonne pi_id comme clef primaire de la table pilote et pas la colonne pi_nom ?

  • a : il peut y avoir des noms identiques.
  • b : une clé primaire est forcément constitué d’entiers.
  • c : pi_nom est une clé étrangère renvoyant à la table circuit.
Correction (cliquer pour afficher)
En cas d'homonymes (réponse a). Une clé primaire doit être unique.

Estimez le nombre de lignes de la table Tour d’après les informations données dans l’énoncé du concours :

Correction (cliquer pour afficher)
La table Tour contient un enregistrement par tour d'un participant.
Il y en a donc environ autant que de (nombre de championnats) $\times$ (nombre moyen de grands prix par championnat) $\times$ (nombre moyen de pilotes par grand prix) $\times$ (nombre moyen de tours par grand prix).
Cela donne environ $(2022-1950)\times 20 \times 20 \times 60\approx 1,7.10^6$ soit un peu moins de 2 millions de lignes.

Vérifions grâce à la requête suivante :
SELECT COUNT(*)
FROM Tour;
COUNT(*)
517573

On peut supposer que notre surestimation vient des nombreux abandons ayant empêché les pilotes de boucler tous les tours d'un circuit.
Essayons de vérifier cette hypothèse :

Vérifions d'abord que la base de données va bien jusqu'à 2022 :
SELECT gp_date
FROM GrandPrix
ORDER BY gp_date DESC
LIMIT 3;
gp_date
2022-11-20
2022-11-13
2022-10-30

Vérifions ensuite le nombre moyen de tours par participation :
SELECT AVG(nb_tours)
FROM (SELECT MAX(to_num) AS nb_tours
      FROM Tour
      GROUP BY Pa_id);
AVG(nb_tours)
52.94864450127877

L'écart n'est pas assez grand pour expliquer la valeur obtenue...

Vérifions enfin le nombre moyen de course par année :
SELECT COUNT(*)
FROM GrandPrix;
COUNT(*)
1079

Étant donné que $1079/72\approx15$, l'énoncé nous a fait surestimer cette valeur.

Vérifions enfin le nombre moyen de pilotes par grand prix :
SELECT AVG(nb_pilotes)
FROM (SELECT COUNT(pi_id) AS nb_pilotes
      FROM Participation
      GROUP BY gp_id)
AVG(nb_pilotes)
24.0188679245283

Zut, là ça va dans le mauvais sens (on avait prix 20 pilotes par course)...

Reprenons le calcul : $72\times 15 \times 24 \times 53\approx 1,4.10^6$
On reste encore plus de deux fois trop grand...

L'autre hypothèse est que la base de données n'est pas complète.
SELECT COUNT(*) 
FROM (SELECT * 
      FROM Tour
      GROUP BY pa_id);
COUNT(*)
9775
SELECT COUNT(*) 
FROM Participation;
COUNT(*)
25460

Bingo ! Beaucoup de participations (62%) ne semblent pas avoir de données dans la table Tour.

Connectons-nous à la base :

%load_ext sql
%sql sqlite:///s3-tp12/F1.db

Connected: @s3-tp12/F1.db

Écrire une requête SQL qui liste, par ordre chronologique, la date et le nom du circuit de toutes les courses qui se sont déroulées en France (ci_pays = 'France').

Correction (cliquer pour afficher)
SELECT gp_date,ci_nom
FROM (SELECT ci_nom, ci_pays, gp_date
      FROM GrandPrix
      JOIN Circuit ON GrandPrix.ci_id = Circuit.ci_id)
WHERE ci_pays = 'France'
ORDER BY gp_date;
gp_date ci_nom
1950-07-02 Reims-Gueux
1951-07-01 Reims-Gueux
1952-07-06 Rouen-Les-Essarts
1953-07-05 Reims-Gueux
1954-07-04 Reims-Gueux
1956-07-01 Reims-Gueux
1957-07-07 Rouen-Les-Essarts
1958-07-06 Reims-Gueux
1959-07-05 Reims-Gueux
1960-07-03 Reims-Gueux
1961-07-02 Reims-Gueux
1962-07-08 Rouen-Les-Essarts
1963-06-30 Reims-Gueux
1964-06-28 Rouen-Les-Essarts
1965-06-27 Charade Circuit
1966-07-03 Reims-Gueux
1967-07-02 Le Mans
1968-07-07 Rouen-Les-Essarts
1969-07-06 Charade Circuit
1970-07-05 Charade Circuit
1971-07-04 Circuit Paul Ricard
1972-07-02 Charade Circuit
1973-07-01 Circuit Paul Ricard
1974-07-07 Dijon-Prenois
1975-07-06 Circuit Paul Ricard
1976-07-04 Circuit Paul Ricard
1977-07-03 Dijon-Prenois
1978-07-02 Circuit Paul Ricard
1979-07-01 Dijon-Prenois
1980-06-29 Circuit Paul Ricard
1981-07-05 Dijon-Prenois
1982-07-25 Circuit Paul Ricard
1982-08-29 Dijon-Prenois
1983-04-17 Circuit Paul Ricard
1984-05-20 Dijon-Prenois
1985-07-07 Circuit Paul Ricard
1986-07-06 Circuit Paul Ricard
1987-07-05 Circuit Paul Ricard
1988-07-03 Circuit Paul Ricard
1989-07-09 Circuit Paul Ricard
1990-07-08 Circuit Paul Ricard
1991-07-07 Circuit de Nevers Magny-Cours
1992-07-05 Circuit de Nevers Magny-Cours
1993-07-04 Circuit de Nevers Magny-Cours
1994-07-03 Circuit de Nevers Magny-Cours
1995-07-02 Circuit de Nevers Magny-Cours
1996-06-30 Circuit de Nevers Magny-Cours
1997-06-29 Circuit de Nevers Magny-Cours
1998-06-28 Circuit de Nevers Magny-Cours
1999-06-27 Circuit de Nevers Magny-Cours
2000-07-02 Circuit de Nevers Magny-Cours
2001-07-01 Circuit de Nevers Magny-Cours
2002-07-21 Circuit de Nevers Magny-Cours
2003-07-06 Circuit de Nevers Magny-Cours
2004-07-04 Circuit de Nevers Magny-Cours
2005-07-03 Circuit de Nevers Magny-Cours
2006-07-16 Circuit de Nevers Magny-Cours
2007-07-01 Circuit de Nevers Magny-Cours
2008-06-22 Circuit de Nevers Magny-Cours
2018-06-24 Circuit Paul Ricard
2019-06-23 Circuit Paul Ricard
2021-06-20 Circuit Paul Ricard
2022-07-24 Circuit Paul Ricard

Écrire une requête SQL qui liste, pour chaque course de l’année 2021, le nom du circuit, le nom du pilote gagnant et son temps de course (dans cet ordre).

Correction (cliquer pour afficher)
SELECT ci_nom AS "Grand Prix", pi_nom AS Vainqueur,temps
FROM Participation 
JOIN GrandPrix ON GrandPrix.gp_id = Participation.gp_id
JOIN Circuit ON GrandPrix.ci_id = Circuit.ci_id
JOIN Pilote ON Participation.pi_id = Pilote.pi_id
JOIN (SELECT pa_id,SUM(to_temps) as temps
      FROM Tour
      GROUP BY pa_id) AS tpstot
ON Participation.pa_id = tpstot.pa_id
WHERE gp_date >= 2021 AND gp_date < 2022 AND pa_cla = 1;
Grand Prix Vainqueur temps
Bahrain International Circuit Hamilton 5523897
Autodromo Enzo e Dino Ferrari Verstappen 7354598
Autódromo Internacional do Algarve Hamilton 5671421
Circuit de Barcelona-Catalunya Hamilton 5587680
Circuit de Monaco Verstappen 5936820
Baku City Circuit Pérez 8016410
Circuit Paul Ricard Verstappen 5245770
Red Bull Ring Verstappen 4938925
Red Bull Ring Verstappen 5034543
Silverstone Circuit Hamilton 7103284
Hungaroring Ocon 7483199
Circuit de Spa-Francorchamps Verstappen 207071
Circuit Park Zandvoort Verstappen 5405395
Autodromo Nazionale di Monza Ricciardo 4914365
Sochi Autodrom Hamilton 5441001
Istanbul Park Bottas 5464103
Circuit of the Americas Verstappen 5676552
Autódromo Hermanos Rodríguez Verstappen 5919086
Autódromo José Carlos Pace Hamilton 5542851
Losail International Circuit Hamilton 5068471
Jeddah Corniche Circuit Hamilton 7575118
Yas Marina Circuit Verstappen 5417345

Que récupère la requête suivante ?

La requête contient deux petites erreurs et une petite bizarrerie. Les identifier et proposer des corrections.

Correction (cliquer pour afficher)
Pour chaque circuit, on récupère son nom, le nom du pilote qui a fait le meilleur tour, la date à laquelle ce tour a eu lieu et le temps du tour.

Erreurs :
  • faute de frappe to_tmps à la fin
  • bugue car nécessite de préciser dans quelle table prendre les ci_id (même si ce sont les mêmes)
  • bizarre de grouper par ci_id, ci_nom... Un seul des deux suffit !
Requête corrigée :
SELECT ci_nom, pi_nom, gp_date, to_temps
FROM (SELECT Circuit.ci_id, ci_nom, MIN(to_temps) AS mtt
        FROM Circuit
            JOIN GrandPrix ON GrandPrix.ci_id = Circuit.ci_id
            JOIN Participation ON Participation.gp_id = GrandPrix.gp_id
            JOIN Tour ON Tour.pa_id = Participation.pa_id
        GROUP BY
            ci_nom
        ) AS rdc
    JOIN GrandPrix ON GrandPrix.ci_id = rdc.ci_id
    JOIN Participation ON Participation.gp_id = GrandPrix.gp_id
    JOIN Pilote ON Pilote.pi_id = Participation.pi_id
    JOIN Tour ON Tour.pa_id = Participation.pa_id AND to_temps = mtt
ORDER BY
    ci_nom;
ci_nom pi_nom gp_date to_temps
A1-Ring Schumacher 2003-05-18 68337
Albert Park Grand Prix Circuit Leclerc 2022-04-10 80260
Autodromo Enzo e Dino Ferrari Hamilton 2020-11-01 75484
Autodromo Internazionale del Mugello Hamilton 2020-09-13 78833
Autodromo Nazionale di Monza Barrichello 2004-09-12 81046
Autódromo Hermanos Rodríguez Bottas 2021-11-07 77774
Autódromo Internacional do Algarve Hamilton 2020-10-25 78750
Autódromo José Carlos Pace Bottas 2018-11-11 70540
Autódromo Juan y Oscar Gálvez Berger 1997-04-13 87981
Autódromo do Estoril Villeneuve 1996-09-22 82873
Bahrain International Circuit Russell 2020-12-06 55404
Baku City Circuit Leclerc 2019-04-28 103009
Buddh International Circuit Vettel 2011-10-30 87249
Circuit Gilles Villeneuve Bottas 2019-06-09 73078
Circuit Park Zandvoort Hamilton 2021-09-05 71097
Circuit Paul Ricard Vettel 2019-06-23 92740
Circuit de Barcelona-Catalunya Fisichella 2005-05-08 75641
Circuit de Monaco Hamilton 2021-05-23 72909
Circuit de Nevers Magny-Cours Coulthard 2002-07-21 75045
Circuit de Spa-Francorchamps Räikkönen 2004-08-29 105108
Circuit of the Americas Leclerc 2019-11-03 96169
Circuito de Jerez Frentzen 1997-10-26 83135
Fuji Speedway Massa 2008-10-12 78426
Hockenheimring Räikkönen 2004-07-25 73780
Hungaroring Schumacher 2002-08-18 76207
Indianapolis Motor Speedway Barrichello 2004-06-20 70399
Istanbul Park Pablo Montoya 2005-08-21 84770
Jeddah Corniche Circuit Hamilton 2021-12-05 90734
Korean International Circuit Vettel 2011-10-16 99605
Losail International Circuit Verstappen 2021-11-21 83196
Marina Bay Street Circuit Magnussen 2018-09-16 101905
Nürburgring Pablo Montoya 2001-06-24 78354
Red Bull Ring Sainz 2020-07-12 65619
Sepang International Circuit Vettel 2017-10-01 94080
Shanghai International Circuit Schumacher 2004-09-26 92238
Silverstone Circuit Schumacher 2004-07-11 78739
Sochi Autodrom Hamilton 2019-09-29 95761
Suzuka Circuit Hamilton 2019-10-13 90983
Valencia Street Circuit Glock 2009-08-23 98683
Yas Marina Circuit Verstappen 2021-12-12 86103