Ce face ROW_NUMBER()
Funcțiile fereastră calculează valori pe un grup de rânduri, dar păstrează fiecare rând în rezultat. Grupul se definește cu OVER (PARTITION BY ... ORDER BY ...).
ROW_NUMBER() dă fiecărui rând un număr unic, în ordinea din ORDER BY, reluat de la 1 pentru fiecare partiție. Este soluția clasică pentru „primele N din fiecare grup”.
Parametri
| Parametru | Descriere |
|---|---|
PARTITION BY |
Opțional. Coloanele după care se împart rândurile în grupuri. |
ORDER BY |
Ordinea numerotării. |
Ce returnează
Un număr întreg de la 1 în sus.
Exemple
Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.
CREATE TABLE vanzari (
agent VARCHAR(20),
oras VARCHAR(20),
luna INT,
suma INT
);
INSERT INTO vanzari VALUES
('Ana', 'Iași', 1, 1200), ('Ana', 'Iași', 2, 1500), ('Ana', 'Iași', 3, 900),
('Dan', 'Cluj', 1, 900), ('Dan', 'Cluj', 2, 900), ('Dan', 'Cluj', 3, 1700),
('Ioana', 'Iași', 1, 2000), ('Ioana', 'Iași', 2, 1100);
Exemplul 1: Numerotarea lunilor fiecărui agent
SELECT agent, luna, suma,
ROW_NUMBER() OVER (PARTITION BY agent ORDER BY suma DESC) AS loc
FROM vanzari
ORDER BY agent, loc;
Rezultat
+-------+------+------+-----+
| agent | luna | suma | loc |
+-------+------+------+-----+
| Ana | 2 | 1500 | 1 |
| Ana | 1 | 1200 | 2 |
| Ana | 3 | 900 | 3 |
| Dan | 3 | 1700 | 1 |
| Dan | 1 | 900 | 2 |
| Dan | 2 | 900 | 3 |
| Ioana | 1 | 2000 | 1 |
| Ioana | 2 | 1100 | 2 |
+-------+------+------+-----+
Exemplul 2: Cea mai bună lună a fiecărui agent
SELECT agent, luna, suma
FROM (
SELECT agent, luna, suma,
ROW_NUMBER() OVER (PARTITION BY agent ORDER BY suma DESC) AS loc
FROM vanzari
) AS t
WHERE loc = 1
ORDER BY agent;
Rezultat
+-------+------+------+
| agent | luna | suma |
+-------+------+------+
| Ana | 2 | 1500 |
| Dan | 3 | 1700 |
| Ioana | 1 | 2000 |
+-------+------+------+
Greșeli frecvente
- Pui condiția
WHERE ROW_NUMBER() ...direct. Funcțiile fereastră se calculează dupăWHERE, deci trebuie o subinterogare (sau un CTE) ca în exemplul 2.
Comenzi înrudite
RANK(): Clasament cu locuri egale la valori egale și „găuri” după ele (1, 2, 2, 4).DENSE_RANK(): Clasament cu locuri egale la valori egale, fără „găuri” (1, 2, 2, 3).NTILE(): Împarte rândurile în N grupe cât mai egale și spune în care grupă este fiecare rând.