Funkce okna se vztahují na agregační a klasifikační funkce v konkrétním okně (množině řádků). Klauzule OVER se používá s funkcemi okna k definování tohoto okna. Klauzule OVER dělá dvě věci:
- Rozdělí řádky tak, aby vytvořily sadu řádků. (je použita klauzule PARTITION BY)
- Seřadí řádky v těchto oddílech do určitého pořadí. (je použita klauzule ORDER BY)
Poznámka: Pokud nejsou oddíly hotové, pak ORDER BY seřadí všechny řádky tabulky.
Syntax:
SELECT coulmn_name1, window_function(cloumn_name2) OVER([PARTITION BY column_name1] [ORDER BY column_name3]) AS new_column FROM table_name; window_function= any aggregate or ranking function column_name1 = column to be selected coulmn_name2= column on which window function is to be applied column_name3 = column on whose basis partition of rows is to be done new_column= Name of new column table_name= Name of table>
Funkce souhrnného okna
Různé agregační funkce jako SUM(), COUNT(), AVERAGE(), MAX() a MIN() aplikované na určité okno (množinu řádků) se nazývají agregační funkce okna.
Zvažte následující zaměstnanec stůl :
| název | Stáří | oddělení | Plat |
|---|---|---|---|
| Ramesh | dvacet | Finance | 50 000 |
| Hluboký | 25 | Odbyt | 30 000 |
| Suresh | 22 | Finance | 50 000 |
| RAM | 28 | Finance | 20 000 |
| Pradeep | 22 | Odbyt | 20 000 |
Příklad –
Najděte průměrný plat zaměstnanců pro každé oddělení a seřaďte zaměstnance v rámci oddělení podle věku.
SELECT Name, Age, Department, Salary, AVG(Salary) OVER( PARTITION BY Department) AS Avg_Salary FROM employee>
Výsledkem je následující:
| název | Stáří | oddělení | Plat | Prům._plat |
| Ramesh | dvacet | Finance | 50 000 | 40 000 |
| Suresh | 22 | Finance | 50 000 | 40 000 |
| RAM | 28 | Finance | 20 000 | 40 000 |
| Hluboký | 25 | Odbyt | 30 000 | 25 000 |
| Pradeep | 22 | Odbyt | 20 000 | 25 000 |
Všimněte si, jak všechny průměrné platy v konkrétním okně mají stejnou hodnotu.
Podívejme se na další případ:
SELECT Name, Age, Department, Salary, AVG(Salary) OVER( PARTITION BY Department ORDER BY Age) AS Avg_Salary FROM employee>
Zde také řadíme záznamy v rámci oddílu podle věkových hodnot, a tudíž se průměrné hodnoty mění podle seřazeného pořadí.
Výstupem výše uvedeného dotazu bude:
| název | Stáří | oddělení | Plat | Prům._plat |
|---|---|---|---|---|
| Ramesh | dvacet | Finance | 50 000 | 50 000 |
| Suresh | 22 | Finance | 50 000 | 50 000 |
| RAM | 28 | Finance | 20 000 | 40 000 |
| Pradeep | 22 | Odbyt | 20 000 | 20 000 |
| Hluboký | 25 | Odbyt | 30 000 | 25 000 |
Proto bychom měli být opatrní při přidávání pořadí podle klauzulí do okenních funkcí s agregacemi.
Funkce okna hodnocení:
Hodnotící funkce jsou: RANK(), DENSE_RANK(), ROW_NUMBER()
- HODNOST() -
Jak název napovídá, funkce hodnocení přiřadí hodnocení všem řádkům v každém oddílu. Pořadí je přiřazeno tak, že pořadí 1 dané prvnímu řádku a řádkům se stejnou hodnotou je přiřazeno stejné pořadí. Pro další pořadí po dvou stejných hodnotách bude jedna hodnota přeskočena. Pokud například dva řádky sdílejí hodnost 1, další řádek získá hodnost 3, nikoli 2.
- DENSE_RANK() –
Přiřazuje hodnocení každému řádku v rámci oddílu. Stejně jako funkci rank je prvnímu řádku přiřazena hodnost 1 a řádky se stejnou hodnotou mají stejnou hodnost. Rozdíl mezi RANK() a DENSE_RANK() je ten, že v DENSE_RANK() se pro další hodnost po dvou stejných hodnostech použije po sobě jdoucí celé číslo, žádná hodnost se nepřeskočí.
- ROW_NUMBER() –
ROW_NUMBER() dává každému řádku jedinečné číslo. Očísluje řádky od jednoho po celkový počet řádků. Řádky jsou rozděleny do skupin na základě jejich hodnot. Každá skupina se nazývá oddíl. V každém oddílu jsou řádky postupně číslovány. Žádné dva řádky nemají v oddílu stejné číslo. Tím se ROW_NUMBER() liší od RANK() a DENSE_RANK(). ROW_NUMBER() jednoznačně identifikuje každý řádek sekvenčním celým číslem. To pomáhá s různými druhy analýzy dat.
Poznámka -
ORDER BY() by mělo být zadáno povinně při používání funkcí okna pořadí.
Příklad –
Vypočítejte číslo řádku, pořadí, husté pořadí zaměstnanců je tabulka zaměstnanců podle platu v rámci jednotlivých oddělení.
SELECT ROW_NUMBER() OVER (PARTITION BY Department ORDER BY Salary DESC) AS emp_row_no, Name, Department, Salary, RANK() OVER(PARTITION BY Department ORDER BY Salary DESC) AS emp_rank, DENSE_RANK() OVER(PARTITION BY Department ORDER BY Salary DESC) AS emp_dense_rank FROM employee;>
Výstupem výše uvedeného dotazu bude:
| emp_row_no | název | oddělení | Plat | emp_rank | emp_dense_rank |
|---|---|---|---|---|---|
| 1 | Ramesh | Finance | 50 000 | 1 | 1 |
| 2 | Suresh | Finance | 50 000 | 1 | 1 |
| 3 | RAM | Finance | 20 000 | 3 | 2 |
| 1 | Hluboký | Odbyt | 30 000 | 1 | 1 |
| 2 | Pradeep | Odbyt | 20 000 | 2 | 2 |
Můžeme tedy vidět, že jak je uvedeno v definici ROW_NUMBER(), čísla řádků jsou po sobě jdoucí celá čísla v rámci každého oddílu. Také můžeme vidět rozdíl mezi hodností a hustotou hodností, že v husté hodnosti není žádná mezera mezi hodnotami hodnosti, zatímco po opakované hodnosti je mezera v hodnotách hodnosti.