En la clase anterior pillamos para qué sirven las funciones de ventana. Ahora vamos a ver funciones concretas y sus resultados. Los detalles de la sintaxis los veremos en la próxima clase.
Función ROW_NUMBER()
La función ROW_NUMBER() devuelve un número único para cada fila dentro de la ventana. Es simplemente numerar las filas en el orden que defines en ORDER BY.
Sintaxis:
ROW_NUMBER() OVER ([PARTITION BY columna] ORDER BY columna)
Dónde:
PARTITION BY columna(opcional): divide los datos en grupos. Si lo dejas fuera, la numeración será global para todo el conjunto.ORDER BY columna: define el orden de las filas para numerarlas.
Ejemplo. Numerar filas en una tabla
Vamos a mirar la tabla students, que tiene info sobre estudiantes y sus notas.
SELECT * FROM students;
| id | name | score |
|---|---|---|
| 1 | Eva Lang | 95 |
| 2 | Maria Chi | 87 |
| 3 | Alex Lin | 78 |
| 4 | Anna Song | 95 |
| 5 | Otto Mart | 87 |
Ahora vamos a numerar las filas según el orden descendente de sus notas (score):
SELECT
name,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;
Resultado:
| name | score | row_num |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 2 |
| Maria Chi | 87 | 3 |
| Otto Mart | 87 | 4 |
| Alex Lin | 78 | 5 |
Cada fila tiene su número único — teniendo en cuenta el orden descendente de las notas.
Es una operación sencilla pero potente — añadir el número de fila al resultado de la consulta. En un SELECT clásico esto no se puede hacer sin funciones de ventana.
Función RANK()
La función RANK() es muy parecida a ROW_NUMBER(), pero tiene en cuenta los valores iguales. Si varias filas tienen el mismo valor en la ordenación, reciben el mismo rango y el siguiente se salta.
Sintaxis:
RANK() OVER ([PARTITION BY columna] ORDER BY columna)
Ejemplo. Ranquear estudiantes por sus notas
Vamos a usar RANK() con los mismos datos:
SELECT
name,
score,
RANK() OVER (ORDER BY score DESC) AS rank
FROM students;
Resultado:
| name | score | rank |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 3 |
| Otto Mart | 87 | 3 |
| Alex Lin | 78 | 5 |
Aquí las filas con los mismos valores (95 y 87) tienen el mismo rango, y los siguientes rangos se saltan.
Función DENSE_RANK()
DENSE_RANK() se parece a RANK(), pero no salta valores de rango. O sea, si hay filas repetidas, el siguiente rango será solo uno más que el anterior.
Sintaxis:
DENSE_RANK() OVER ([PARTITION BY columna] ORDER BY columna)
Ejemplo. Ranquear de forma densa
Usamos DENSE_RANK() con los mismos datos:
SELECT
name,
score,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM students;
Resultado:
| name | score | dense_rank |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 2 |
| Otto Mart | 87 | 2 |
| Alex Lin | 78 | 3 |
Aquí, a diferencia de RANK(), los valores de rango suben sin saltos.
Función NTILE()
La función NTILE() divide las filas en grupos iguales (cuantiles) y le da a cada fila el número de grupo.
Sintaxis:
NTILE(n) OVER ([PARTITION BY columna] ORDER BY columna)
n: cuántos grupos quieres crear con los datos.
Ejemplo. Dividir estudiantes en 3 grupos
Vamos a dividir a los estudiantes en 3 grupos según sus notas (de mayor a menor):
SELECT
name,
score,
NTILE(3) OVER (ORDER BY score DESC) AS group_num
FROM students;
Resultado:
| name | score | group_num |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 2 |
| Otto Mart | 87 | 2 |
| Alex Lin | 78 | 3 |
Ojo: si no se puede dividir las filas en grupos exactamente iguales, las filas extra van a los primeros grupos. En este ejemplo, los dos primeros grupos tienen dos filas y el último solo una.
¿Cuándo usar cada función?
ROW_NUMBER(): para numerar filas de forma única según el orden.RANK(): para ranquear teniendo en cuenta valores iguales y saltando el siguiente rango.DENSE_RANK(): para ranquear con valores iguales pero sin saltar rangos.NTILE(): Para dividir filas en grupos iguales.
Todas estas funciones te ayudan a analizar datos a otro nivel. Úsalas cuando necesites flexibilidad para calcular números de orden o dividir datos en grupos.
GO TO FULL VERSION