Défi
Énoncé
La table produits contient les colonnes id (INT), nom (TEXT), categorie (TEXT) et prix (NUMERIC). Écrire une requête SQL qui retourne, pour chaque catégorie, les 3 produits ayant les prix les plus élevés. En cas d'égalité de prix, l'ordre entre ex-aequo peut être arbitraire. Le résultat doit être trié par catégorie puis par rang.
Contraintes
- Utiliser
ROW_NUMBER() OVER (PARTITION BY categorie ORDER BY prix DESC)dans une sous-requête ou un CTE. - Filtrer ensuite les lignes avec
rang <= 3dans la requête extérieure. - Colonnes de sortie :
categorie,nom,prix,rang. - PostgreSQL 15+.
Exemple
Jeu de données :
CREATE TABLE produits (id INT, nom TEXT, categorie TEXT, prix NUMERIC);
INSERT INTO produits VALUES
(1, 'Alpha', 'Electronique', 999.00),
(2, 'Beta', 'Electronique', 799.00),
(3, 'Gamma', 'Electronique', 650.00),
(4, 'Delta', 'Electronique', 499.00),
(5, 'Epsilon', 'Vetements', 120.00),
(6, 'Zeta', 'Vetements', 95.00),
(7, 'Eta', 'Vetements', 80.00),
(8, 'Theta', 'Vetements', 60.00),
(9, 'Iota', 'Livres', 45.00),
(10, 'Kappa', 'Livres', 30.00);
Requête :
WITH classes AS (
SELECT
categorie,
nom,
prix,
ROW_NUMBER() OVER (PARTITION BY categorie ORDER BY prix DESC) AS rang
FROM produits
)
SELECT categorie, nom, prix, rang
FROM classes
WHERE rang <= 3
ORDER BY categorie, rang;
Résultat attendu :
categorie | nom | prix | rang
--------------+---------+--------+------
Electronique | Alpha | 999.00 | 1
Electronique | Beta | 799.00 | 2
Electronique | Gamma | 650.00 | 3
Livres | Iota | 45.00 | 1
Livres | Kappa | 30.00 | 2
Vetements | Epsilon | 120.00 | 1
Vetements | Zeta | 95.00 | 2
Vetements | Eta | 80.00 | 3
(8 lignes)