đ Quâest-ce quâune fonction fenĂȘtre ?#
Une fonction fenĂȘtre :
- Travaille ligne par ligne,
- Peut accéder aux lignes voisines,
- Ne réduit pas le nombre de lignes (contrairement au
GROUP BY).
Elle repose sur la clause :
OVER (
PARTITION BY ...
ORDER BY ...
ROWS BETWEEN ...
)
đ§ Navigation dans les lignes#
LAG(): valeur prĂ©cĂ©denteSELECT client_id, date_commande, LAG(date_commande) OVER ( PARTITION BY client_id ORDER BY date_commande ) AS prev_date FROM commandes;LEAD(): valeur suivanteSELECT client_id, date_commande, LEAD(date_commande) OVER ( PARTITION BY client_id ORDER BY date_commande ) AS next_date FROM commandes;FIRST_VALUE()/LAST_VALUE():SELECT client_id, montant, FIRST_VALUE(montant) OVER ( PARTITION BY client_id ORDER BY date_commande ) AS montant_initial FROM commandes;â ïž
LAST_VALUE()nécessite souvent unROWS BETWEEN UNBOUNDED FOLLOWINGselon les moteurs.
đ Fonctions cumulĂ©es#
Exemple : cumul du montant des commandes
SELECT
client_id,
date_commande,
montant,
SUM(montant) OVER (
PARTITION BY client_id
ORDER BY date_commande
) AS cumul_client
FROM commandes;
âïž Options de fenĂȘtre#
| Option | Effet |
|---|---|
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW | Cumul depuis le début |
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING | FenĂȘtre glissante autour de chaque ligne |
PARTITION BY | Réinitialise le calcul par groupe |
ORDER BY | Définit la progression dans le groupe |
𧯠PiÚges fréquents#
| â ïž PiĂšge | â Solution |
|---|---|
Oublier ORDER BY â rĂ©sultats instables | Toujours ordonner les valeurs |
Mélanger GROUP BY avec OVER() | Comprendre que OVER ne réduit pas les lignes |
LAST_VALUE() renvoie la valeur courante | Ajouter ROWS BETWEEN UNBOUNDED FOLLOWING |
| FenĂȘtre trop large â rĂ©sultats absurdes | Ajuster ROWS BETWEEN ... selon le besoin |
đïžââïž EntraĂźnement#
- Obtenir la date précédente et suivante de chaque commande (LAG / LEAD).
- Calculer lâĂ©volution du montant dâun client (montant courant vs prĂ©cĂ©dent).
- Construire le montant cumulé par client.
- Calculer la différence entre deux jours successifs pour un produit.
duckdb.sql("""
SELECT
client_id, date_commande, montant,
LAG(montant) OVER (PARTITION BY client_id ORDER BY date_commande) AS prev,
SUM(montant) OVER (PARTITION BY client_id ORDER BY date_commande) AS cumul
FROM commandes
""").df()