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.