Vensterfuncties zijn van toepassing op het aggregeren en rangschikken van functies over een bepaald venster (reeks rijen). De OVER-clausule wordt gebruikt met vensterfuncties om dat venster te definiëren. OVER-clausule doet twee dingen:
- Verdeelt rijen om een reeks rijen te vormen. (clausule PARTITION BY wordt gebruikt)
- Ordent rijen binnen die partities in een bepaalde volgorde. (ORDER BY-clausule wordt gebruikt)
Opmerking: Als de partities nog niet zijn voltooid, ordent ORDER BY alle rijen van de tabel.
Syntaxis:
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>
Geaggregeerde vensterfunctie
Verschillende aggregatiefuncties zoals SUM(), COUNT(), AVERAGE(), MAX() en MIN() die op een bepaald venster (reeks rijen) worden toegepast, worden aggregatievensterfuncties genoemd.
Stel je de volgende situatie voor medewerker tafel :
| Naam | Leeftijd | Afdeling | Salaris |
|---|---|---|---|
| Ramesh | twintig | Financiën | 50.000 |
| Diep | 25 | verkoop | 30.000 |
| Zeker | 22 | Financiën | 50000 |
| Ram | 28 | Financiën | 20.000 |
| Pradeep | 22 | verkoop | 20.000 |
Voorbeeld -
Vind het gemiddelde salaris van medewerkers voor elke afdeling en rangschik de medewerkers binnen een afdeling op leeftijd.
SELECT Name, Age, Department, Salary, AVG(Salary) OVER( PARTITION BY Department) AS Avg_Salary FROM employee>
Dit levert het volgende op:
| Naam | Leeftijd | Afdeling | Salaris | Gem_Salaris |
| Ramesh | twintig | Financiën | 50.000 | 40.000 |
| Zeker | 22 | Financiën | 50.000 | 40.000 |
| Ram | 28 | Financiën | 20.000 | 40.000 |
| Diep | 25 | verkoop | 30.000 | 25.000 |
| Pradeep | 22 | verkoop | 20.000 | 25.000 |
Merk op dat alle gemiddelde salarissen in een bepaald venster dezelfde waarde hebben.
Laten we een ander geval bekijken:
SELECT Name, Age, Department, Salary, AVG(Salary) OVER( PARTITION BY Department ORDER BY Age) AS Avg_Salary FROM employee>
Hier ordenen we ook de records binnen de partitie op basis van leeftijdswaarden en daarom veranderen de gemiddelde waarden volgens de gesorteerde volgorde.
De uitvoer van bovenstaande query zal zijn:
| Naam | Leeftijd | Afdeling | Salaris | Gem_Salaris |
|---|---|---|---|---|
| Ramesh | twintig | Financiën | 50.000 | 50.000 |
| Zeker | 22 | Financiën | 50.000 | 50.000 |
| Ram | 28 | Financiën | 20.000 | 40.000 |
| Pradeep | 22 | verkoop | 20.000 | 20.000 |
| Diep | 25 | verkoop | 30.000 | 25.000 |
Daarom moeten we voorzichtig zijn bij het toevoegen van order-by-clausules aan vensterfuncties met aggregaten.
Rangschikkingsvensterfuncties:
Rangschikkingsfuncties zijn: RANK(), DENSE_RANK(), ROW_NUMBER()
- RANG() –
Zoals de naam al doet vermoeden, wijst de rangfunctie een rang toe aan alle rijen binnen elke partitie. De rang wordt zodanig toegewezen dat rang 1 aan de eerste rij wordt gegeven en rijen met dezelfde waarde dezelfde rang krijgen. Voor de volgende rang na twee dezelfde rangwaarden wordt één rangwaarde overgeslagen. Als twee rijen bijvoorbeeld rang 1 delen, krijgt de volgende rij rang 3, en niet rang 2.
- DENSE_RANK() –
Het wijst een rang toe aan elke rij binnen de partitie. Net zoals de rangfunctie aan de eerste rij rang 1 krijgt toegewezen en rijen met dezelfde waarde dezelfde rang hebben. Het verschil tussen RANK() en DENSE_RANK() is dat in DENSE_RANK() voor de volgende rang na twee dezelfde rang een opeenvolgend geheel getal wordt gebruikt en geen rang wordt overgeslagen.
- RIJ NUMMER() -
ROW_NUMBER() geeft elke rij een uniek nummer. Het nummert rijen van één tot het totaal aantal rijen. De rijen worden in groepen geplaatst op basis van hun waarden. Elke groep wordt een partitie genoemd. In elke partitie krijgen rijen de een na de ander nummer. Geen twee rijen hebben hetzelfde nummer in een partitie. Dit maakt ROW_NUMBER() anders dan RANK() en DENSE_RANK(). ROW_NUMBER() identificeert op unieke wijze elke rij met een opeenvolgend geheel getal. Dit helpt bij verschillende soorten data-analyse.
Opmerking -
ORDER BY() moet verplicht worden opgegeven bij het gebruik van rangschikkingsvensterfuncties.
Voorbeeld -
Bereken rijnummer, rang, dichte rang van werknemers is de werknemerstabel volgens salaris binnen elke afdeling.
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;>
De uitvoer van bovenstaande query zal zijn:
| emp_row_nr | Naam | Afdeling | Salaris | emp_rang | emp_dense_rank |
|---|---|---|---|---|---|
| 1 | Ramesh | Financiën | 50.000 | 1 | 1 |
| 2 | Zeker | Financiën | 50.000 | 1 | 1 |
| 3 | Ram | Financiën | 20.000 | 3 | 2 |
| 1 | Diep | verkoop | 30.000 | 1 | 1 |
| 2 | Pradeep | verkoop | 20.000 | 2 | 2 |
We kunnen dus zien dat, zoals vermeld in de definitie van ROW_NUMBER(), de rijnummers opeenvolgende gehele getallen zijn binnen elke partitie. We kunnen ook het verschil zien tussen rang en dichte rang dat er bij een dichte rang geen kloof is tussen rangwaarden, terwijl er wel een kloof is in rangwaarden na herhaalde rang.