Fonctions de fenêtre
IntermédiaireUne fonction de fenêtre calcule une valeur sur un ensemble de lignes liées à la ligne courante, sans les regrouper : on garde le détail et on ajoute un calcul.
SELECT client_id, id, total, cree_le,
row_number() OVER (PARTITION BY client_id ORDER BY cree_le DESC) AS rang,
sum(total) OVER (PARTITION BY client_id) AS total_client,
sum(total) OVER (PARTITION BY client_id ORDER BY cree_le) AS cumul,
lag(total) OVER (PARTITION BY client_id ORDER BY cree_le) AS commande_precedente
FROM commandes;
Les fonctions à connaître#
| Fonction | Rôle |
|---|---|
row_number() | Numéro unique dans la partition (1, 2, 3…) |
rank() / dense_rank() | Rang avec ex æquo (rank laisse des trous, dense_rank non) |
lag(x) / lead(x) | Valeur de la ligne précédente / suivante |
first_value(x) / last_value(x) | Première / dernière valeur de la fenêtre |
sum(x), avg(x), count(x) | Agrégat en fenêtre : total, cumul, moyenne mobile |
ntile(n) | Découpe en n tranches (quartiles, déciles) |
Top N par groupe#
Le cas d'usage classique : la dernière commande de chaque client.
SELECT *
FROM (
SELECT o.*,
row_number() OVER (PARTITION BY client_id ORDER BY cree_le DESC) AS rn
FROM commandes o
) t
WHERE rn = 1;
Piège : on ne peut pas filtrer directement sur une fonction de fenêtre dans le
WHERE(elle est évaluée après). Il faut une sous-requête ou une CTE, comme ci-dessus.