Cliquez sur cette invitation pour récupérer le repository du TP.
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.
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.
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.
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.
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.
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édiaireAutojointure
(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 colonnepi_nom
?
pi_nom
est une clé étrangère renvoyant à la table circuit
.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 :
La tableTour
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 tableTour
.
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'
).
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).
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.
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 :Requête corrigée :
- 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 !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