Les funcions de finestra s'apliquen a funcions d'agregació i classificació en una finestra determinada (conjunt de files). La clàusula OVER s'utilitza amb les funcions de finestra per definir aquesta finestra. La clàusula OVER fa dues coses:
- Particioneu les files per formar un conjunt de files. (S'utilitza la clàusula PARTITION BY)
- Ordena les files dins d'aquestes particions en un ordre particular. (S'utilitza la clàusula ORDER BY)
Nota: Si les particions no es fan, aleshores ORDER BY ordena totes les files de la taula.
Sintaxi:
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>
Funció de finestra agregada
Diverses funcions agregades com SUM(), COUNT(), AVERAGE(), MAX() i MIN() aplicades sobre una finestra determinada (conjunt de files) s'anomenen funcions de finestra agregada.
Considereu el següent empleat taula:
| Nom | Edat | Departament | Sou |
|---|---|---|---|
| Ramesh | 20 | Finances | 50, 000 |
| Profund | 25 | Vendes | 30, 000 |
| Suresh | 22 | Finances | 50000 |
| Ram | 28 | Finances | 20, 000 |
| Pradeep | 22 | Vendes | 20, 000 |
Exemple -
Trobeu el salari mitjà dels empleats per a cada departament i ordeneu els empleats d'un departament per edat.
SELECT Name, Age, Department, Salary, AVG(Salary) OVER( PARTITION BY Department) AS Avg_Salary FROM employee>
Això genera el següent:
| Nom | Edat | Departament | Sou | Salari_mitjana |
| Ramesh | 20 | Finances | 50,000 | 40,000 |
| Suresh | 22 | Finances | 50,000 | 40,000 |
| Ram | 28 | Finances | 20,000 | 40,000 |
| Profund | 25 | Vendes | 30,000 | 25,000 |
| Pradeep | 22 | Vendes | 20,000 | 25,000 |
Observeu com tots els salaris mitjans d'una finestra concreta tenen el mateix valor.
com mostrar l'aplicació a Android
Considerem un altre cas:
SELECT Name, Age, Department, Salary, AVG(Salary) OVER( PARTITION BY Department ORDER BY Age) AS Avg_Salary FROM employee>
Aquí també ordenem els registres dins de la partició segons els valors d'edat i, per tant, els valors mitjans canvien segons l'ordre ordenat.
La sortida de la consulta anterior serà:
| Nom | Edat | Departament | Sou | Salari_mitjana |
|---|---|---|---|---|
| Ramesh | 20 | Finances | 50,000 | 50,000 |
| Suresh | 22 | Finances | 50,000 | 50,000 |
| Ram | 28 | Finances | 20,000 | 40,000 |
| Pradeep | 22 | Vendes | 20,000 | 20,000 |
| Profund | 25 | Vendes | 30,000 | 25,000 |
Per tant, hauríem d'anar amb compte quan afegim clàusules d'ordre per a les funcions de finestra amb agregats.
Funcions de la finestra de classificació:
Les funcions de classificació són, RANK(), DENSE_RANK(), ROW_NUMBER()
- RANK() –
Com el seu nom indica, la funció de classificació assigna un rang a totes les files de cada partició. El rang s'assigna de manera que el rang 1 es dóna a la primera fila i les files que tenen el mateix valor s'assignen el mateix rang. Per a la classificació següent després de dos valors de classificació iguals, s'ometrà un valor de classificació. Per exemple, si dues files comparteixen el rang 1, la següent fila obté el rang 3, no 2.
- DENSE_RANK() –
Assigna un rang a cada fila dins de la partició. Igual que la funció de classificació, la primera fila s'assigna el rang 1 i les files que tenen el mateix valor tenen el mateix rang. La diferència entre RANK() i DENSE_RANK() és que a DENSE_RANK(), per a la classificació següent després de dues mateixes classificacions, s'utilitza un enter consecutiu, no s'omet cap classificació.
- ROW_NUMBER() –
ROW_NUMBER() dóna a cada fila un número únic. Numera les files des d'una fins al total de files. Les files es classifiquen en grups en funció dels seus valors. Cada grup s'anomena partició. A cada partició, les files obtenen números una darrere l'altra. No hi ha dues files que tinguin el mateix nombre en una partició. Això fa que ROW_NUMBER() sigui diferent de RANK() i DENSE_RANK(). ROW_NUMBER() identifica de manera única cada fila amb un nombre seqüencial. Això ajuda amb diferents tipus d'anàlisi de dades.
Nota -
ORDER BY() s'ha d'especificar obligatòriament mentre s'utilitzen les funcions de la finestra de classificació.
Exemple -
Calcula el número de fila, el rang, el rang dens dels empleats és la taula dels empleats segons el salari de cada departament.
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;>
La sortida de la consulta anterior serà:
| emp_row_no | Nom | Departament | Sou | emp_rank | rang_emp_dense |
|---|---|---|---|---|---|
| 1 | Ramesh | Finances | 50, 000 | 1 | 1 |
| 2 | Suresh | Finances | 50, 000 | 1 | 1 |
| 3 | Ram | Finances | 20, 000 | 3 | 2 |
| 1 | Profund | Vendes | 30, 000 | 1 | 1 |
| 2 | Pradeep | Vendes | 20, 000 | 2 | 2 |
Així, podem veure que, tal com s'esmenta a la definició de ROW_NUMBER(), els números de fila són nombres enters consecutius dins de cada partició. A més, podem veure la diferència entre el rang i el rang dens que en el rang dens no hi ha cap bretxa entre els valors de rang mentre que hi ha una bretxa en els valors de rang després de la classificació repetida.