logo

Fönsterfunktioner i SQL

Fönsterfunktioner gäller för aggregering och rangordning av funktioner över ett visst fönster (uppsättning rader). OVER-satsen används med fönsterfunktioner för att definiera det fönstret. OVER-satsen gör två saker:

  • Partitionera rader för att bilda en uppsättning rader. (PARTITION BY-sats används)
  • Ordnar rader inom dessa partitioner i en viss ordning. (ORDER BY-sats används)

Notera: Om partitioner inte är klara, beställer ORDER BY alla rader i tabellen.



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>

Aggregerad fönsterfunktion
Olika aggregatfunktioner som SUM(), COUNT(), AVERAGE(), MAX() och MIN() som tillämpas över ett visst fönster (uppsättning rader) kallas aggregatfönsterfunktioner.

Tänk på följande anställd tabell:



namn Ålder Avdelning Lön
Ramesh tjugo Finansiera 50 000
Djup 25 Försäljning 30 000
Suresh 22 Finansiera 50 000
Bagge 28 Finansiera 20 000
Pradeep 22 Försäljning 20 000

Exempel –
Hitta medellönen för anställda för varje avdelning och beställ anställda inom en avdelning efter ålder.

SELECT Name, Age, Department, Salary,   AVG(Salary) OVER( PARTITION BY Department) AS Avg_Salary  FROM employee>

Detta ger ut följande:

namn Ålder Avdelning Lön Genomsnittlig_lön
Ramesh tjugo Finansiera 50 000 40 000
Suresh 22 Finansiera 50 000 40 000
Bagge 28 Finansiera 20 000 40 000
Djup 25 Försäljning 30 000 25 000
Pradeep 22 Försäljning 20 000 25 000

Lägg märke till hur alla medellöner i ett visst fönster har samma värde.



Låt oss överväga ett annat fall:

SELECT Name, Age, Department, Salary,   AVG(Salary) OVER( PARTITION BY Department ORDER BY Age) AS Avg_Salary  FROM employee>

Här ordnar vi också posterna inom partitionen enligt åldersvärden och därmed ändras medelvärdena enligt den sorterade ordningen.
Utdata från ovanstående fråga kommer att vara:

namn Ålder Avdelning Lön Genomsnittlig_lön
Ramesh tjugo Finansiera 50 000 50 000
Suresh 22 Finansiera 50 000 50 000
Bagge 28 Finansiera 20 000 40 000
Pradeep 22 Försäljning 20 000 20 000
Djup 25 Försäljning 30 000 25 000

Därför bör vi vara försiktiga när vi lägger till ordföljdssatssatser till fönsterfunktioner med aggregat.

Rangordningsfönsterfunktioner:
Rankningsfunktionerna är RANK(), DENSE_RANK(), ROW_NUMBER()

  • RANK() –
    Som namnet antyder tilldelar rankfunktionen rang till alla rader inom varje partition. Rangen tilldelas så att rang 1 som ges till den första raden och rader med samma värde tilldelas samma rang. För nästa rankning efter två samma rankvärden kommer ett rankvärde att hoppas över. Till exempel, om två rader delar rang 1, får nästa rad rang 3, inte 2.
  • DENSE_RANK() –
    Den tilldelar rang till varje rad inom partitionen. Precis som rangfunktionen tilldelas första raden rang 1 och rader med samma värde har samma rang. Skillnaden mellan RANK() och DENSE_RANK() är att i DENSE_RANK(), för nästa rankning efter två samma rank, används konsekutiva heltal, ingen rank hoppas över.
  • ROW_NUMBER() –
    ROW_NUMBER() ger varje rad ett unikt nummer. Den numrerar rader från en till totala raderna. Raderna delas in i grupper utifrån deras värderingar. Varje grupp kallas en partition. I varje partition får raderna nummer efter varandra. Inga två rader har samma nummer i en partition. Detta skiljer ROW_NUMBER() från RANK() och DENSE_RANK(). ROW_NUMBER() identifierar varje rad unikt med ett sekventiellt heltal. Detta hjälper till med olika typer av dataanalys.

Notera -
ORDER BY() bör anges obligatoriskt när du använder rank window-funktioner.

Exempel –
Beräkna radnr, rang, tät rang av anställda är personaltabell enligt lön inom varje avdelning.

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;>

Utdata från ovanstående fråga kommer att vara:

emp_row_no namn Avdelning Lön emp_rank emp_dense_rank
1 Ramesh Finansiera 50 000 1 1
2 Suresh Finansiera 50 000 1 1
3 Bagge Finansiera 20 000 3 2
1 Djup Försäljning 30 000 1 1
2 Pradeep Försäljning 20 000 2 2

Så vi kan se att som nämnts i definitionen av ROW_NUMBER() är radnumren på varandra följande heltal inom varje partition. Vi kan också se skillnad mellan rang och tät rang att i tät rang finns det inget gap mellan rangvärden medan det finns gap i rangvärden efter upprepad rangordning.