Lecții din modul (2/4)
Funcții ferestre: clasamente și calcule pe grup
O funcție fereastră este o funcție care operează pe un „grup de rânduri”
(fereastra) dar — spre deosebire de GROUP BY — nu reduce numărul de
rânduri: o valoare calculată peste fereastră este atașată fiecărui rând al
rezultatul final.
Este instrumentul potrivit pentru clasamente, numerotare progresivă, procente
peste un total de grup și multe alte operațiuni care sunt incomode sau
imposibil cu GROUP BY.
Sintaxa: function() OVER (…)
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)Componente:
PARTITION BY— definește „grupurile” (cum ar fiGROUP BY, dar rândurile stați separat);ORDER BYîn interiorulOVER(…)— definește ordinea în cadrul compartimentare.
OVER () (paranteze goale) înseamnă „întregul tabel ca o singură fereastră”.
Util pentru calcule precum „procent din total”.
Funcții de clasare
ROW_NUMBER() OVER (PARTITION BY p ORDER BY o)
RANK() OVER (PARTITION BY p ORDER BY o)
DENSE_RANK() OVER (PARTITION BY p ORDER BY o)Diferențe (cu valori 100, 100, 90, 80):
| Funcția | Poziții |
|---|---|
ROW_NUMBER | 1, 2, 3, 4 (întotdeauna unic) |
RANK | 1, 1, 3, 4 (legăturile împărtășesc o poziție, lasă „goluri”) |
DENSE_RANK | 1, 1, 2, 3 (legăturile împart o poziție, fără lacune) |
Exemplu: clasarea produselor pe categorie
SELECT name,
category_id,
price,
RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS rank
FROM products
ORDER BY category_id, rank;Pentru fiecare category_id, RANK repornește de la 1 și comandă descendent
preț: obțineți clasamentul produselor în cadrul fiecărei categorii, într-una singură
impuscat.
Numerotare progresivă
-- Progressive order number for each customer:
SELECT id,
customer_id,
ordered_at,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_at) AS row_num
FROM orders
ORDER BY customer_id, row_num;Prima comandă a fiecărui client va avea row_num = 1, a doua 2 etc.
Încearcă
Pentru fiecare produs afișați numele, categoria_id, prețul și clasamentul (clasamentul prin preț descendent ÎN cadrul categoriei; utilizați RANK). Ordonați după categorie_id crescător și rang crescător.
Afișează indiciu
PARTITION BY categorie_id grupuri, ORDER BY pret DESC comenzi din cadrul grupului.
Soluție disponibilă după 3 încercări
Exercițiu de revizuire
Pentru fiecare comandă afișați id, customer_id, ordered_at și row_num (ROW_NUMBER progresiv per client, ordonat crescător ordered_at). Comandă după customer_id și row_num.
Afișează indiciu
ROW_NUMBER este întotdeauna unic în cadrul partiției.
Soluție disponibilă după 3 încercări