logo

Okenní funkce v SQL

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.