***** Exercice 1 ***** SELECT * FROM Resultats WHERE Score = ( SELECT MAX(Score) FROM Resultats ) Éventuellement LIMIT 1 pour n'avoir qu'un enregistrement (arbitraire) en cas d'égalité. … ou plus simplement : SELECT * FROM Resultats ORDER BY Score DESC LIMIT 1 (là c'est garanti qu'il n'y a qu'un seul enregistrement) L'étoile est la bienvenue vu qu'on récupère tout. ***** Exercice 2 ***** SELECT MAX(Score) FROM Resultats WHERE Date = d Puisqu'on ne récupère qu'un champ agrégé, on n'a pas besoin de tant d'artifices. Bien entendu, on peut une fois de plus passer par le tri. SELECT Score FROM Resultats WHERE Date = d ORDER BY Score DESC LIMIT 1 ***** Exercice 3 ***** SELECT COUNT(*) FROM Resultats WHERE Score > s AND Date = d Même remarque qu'à l'exercice 2. L'inégalité peut être large, mais on prépare le terrain pour la suite ici. ***** Exercice 4 ***** SELECT COUNT(*) FROM Resultats WHERE Score > ( SELECT Score FROM Resultats WHERE Id = n AND Date = d ) AND Date = d On récupère un seul résultat, donc tout va relativement bien. Autre possibilité en faisant d'ores et déjà une auto-jointure : SELECT COUNT(*) FROM Resultats AS R1 JOIN Resultats AS R2 ON R1.Date = R2.Date WHERE R1.Date = d AND R2.Id = n AND R1.Score > R2.Score ***** Exercice 5 ***** SELECT R1.Id, R2.Id FROM Resultats AS R1 JOIN Resultats AS R2 ON R1.Date = R2.Date WHERE R1.Date = d AND R1.Score > R2.Score Le mot-clé AS n'est pas nécessaire dans un renommage, mais je n'envisage pas de le retirer, c'est une histoire de présentation. Version alternative hors-programme en utilisant autre chose qu'une égalité dans la jointure : SELECT R1.Id, R2.Id FROM Resultats AS R1 JOIN Resultats AS R2 ON R1.Score > R2.Score WHERE R1.Date = d AND R2.Date = d ***** Exercice 6 ***** SELECT Id, 1 AS Place FROM Resultats WHERE Score = ( SELECT MAX(Score) FROM Resultats WHERE Date = d ) AND Date = d UNION SELECT R2.Id, COUNT(*)+1 AS Place FROM Resultats AS R1 JOIN Resultats AS R2 ON R1.Date = R2.Date WHERE R1.Date = d AND R1.Score > R2.Score GROUP BY R2.Id ORDER BY Place C'est vrai que ce serait plus facile avec des <= car on n'aurait pas les maxima qui disparaissent, mais le vrai classement s'obtient en connaissant le nombre de personnes qui ont strictement plus (sinon c'est compliqué de le récupérer, et on préfère alors utiliser un programme annexe). Pour le cas où on voudrait le classement général sur les totaux, une table dérivée s'impose, et donc on ne prendra pas les résultats dans Resultats WHERE Date = d mais dans (SELECT SUM(Score) AS Total FROM Resultats GROUP BY Id), une table dérivée qui doit avoir un alias suivant la version de SQL. La requête devient alors SELECT Id, 1 AS Place FROM ( SELECT SUM(Score) AS Total FROM Resultats GROUP BY Id ) AS td WHERE Total = ( SELECT MAX(Total) FROM ( SELECT SUM(Score) AS Total FROM Resultats GROUP BY Id ) AS td2 ) UNION SELECT R2.Id, COUNT(*)+1 AS Place FROM ( SELECT SUM(Score) AS Total FROM Resultats GROUP BY Id ) AS R1 JOIN ( SELECT SUM(Score) AS Total FROM Resultats GROUP BY Id ) AS R2 WHERE R1.Total > R2.Total GROUP BY R2.Id ORDER BY Place ***** Exercice 7 ***** SELECT Id, 1 AS Place FROM Resultats WHERE Score = ( SELECT MAX(Score) FROM Resultats WHERE Date = d ) AND Date = d UNION SELECT R2.Id, COUNT(*)+1 AS Place FROM Resultats AS R1 JOIN Resultats AS R2 ON R1.Date = R2.Date WHERE R1.Date = d AND R1.Score > R2.Score AND R2.Score >= ( SELECT AVG(Score) FROM Resultats WHERE Date = d ) GROUP BY R2.Id ORDER BY Place Évidemment, les maxima sont au-dessus de la moyenne donc on ne va pas se fatiguer. Tel quel c'est plus simple de retirer les éléments inférieurs à la moyenne avant le regroupement que de faire un HAVING qui nécessiterait des précautions. L'adaptation de la requête alternative de l'exercice précédent est laissée au lecteur. ***** Exercice 8 ***** SELECT Id, 1 AS Place FROM Resultats WHERE Score = ( SELECT MAX(Score) FROM Resultats WHERE Date = d ) AND Date = d UNION SELECT R2.Id, COUNT(*)+1 AS Place FROM Resultats AS R1 JOIN Resultats AS R2 WHERE R1.Score > R2.Score AND R1.Date = d AND R2.Date = d GROUP BY R2.Id HAVING Place <= ((SELECT COUNT(*) FROM Resultats WHERE Date = d)+1)/2 ORDER BY Place L'attribut Place étant le résultat de l'application d'une fonction d'agrégation, on ne peut pas filtrer suivant ses résultats en amont du regroupement, d'où la clause HAVING. L'inclusion des égalités fait passer l'exercice d'impensable à violent ! En particulier, les maxima sont toujours aussi tranquilles. L'adaptation de la requête alternative de l'exercice précédent est également laissée au lecteur. ***** Exercice 9 ***** SELECT Id FROM Resultats GROUP BY Id HAVING COUNT(*) = ( SELECT COUNT(DISTINCT Date) FROM Resultats )