Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 2 de 426/57 en el curso~14 min
Lecciones del módulo (2/4)

Funciones de ventana: clasificaciones y cálculos por grupo

Una función de ventana es una función que opera en un "grupo de filas" (la ventana) pero, a diferencia de GROUP BY, no reduce el número de filas: se adjunta un valor calculado en la ventana a cada fila del resultado final.

Es la herramienta adecuada para clasificaciones, numeración progresiva y porcentajes. sobre el total de un grupo y muchas otras operaciones que son incómodas o imposible con GROUP BY.

La sintaxis: function() OVER (…)

SQL
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)

Componentes:

  • PARTITION BY — define los "grupos" (como GROUP BY, pero las filas permanecer separado);
  • ORDER BY dentro de OVER(…): define el orden dentro del partición.

OVER () (paréntesis vacíos) significa "toda la tabla como una sola ventana". Útil para cálculos como "porcentaje del total".

Funciones de clasificación

Code
ROW_NUMBER() OVER (PARTITION BY p ORDER BY o)
RANK()       OVER (PARTITION BY p ORDER BY o)
DENSE_RANK() OVER (PARTITION BY p ORDER BY o)

Diferencias (con valores 100, 100, 90, 80):

FunciónPosiciones
CÓDIGOPH01, 2, 3, 4 (siempre único)
CÓDIGOPH11, 1, 3, 4 (los empates comparten una posición, dejan "espacios")
CÓDIGOPH21, 1, 2, 3 (los empates comparten posición, sin espacios)

Ejemplo: ranking de productos por categoría

SQL
SELECT name,
       category_id,
       price,
       RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS rank
FROM   products
ORDER BY category_id, rank;

Para cada category_id el RANK se reinicia desde 1 y ordena descendente precio: obtienes la clasificación de productos dentro de cada categoría, en uno tiro.

Numeración progresiva

SQL
-- Progressive order number for each customer:
SELECT id,
       customer_id,
       ordered_at,
       ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_at) AS row_num
FROM   orders
ORDER BY customer_id, row_num;

El primer pedido de cada cliente tendrá row_num = 1, el segundo 2, etc.

Pruébalo

Ejercicio#sql.m7.l2.e1
Intentos: 0Cargando...

Para cada producto, muestre el nombre, el ID de categoría, el precio y la clasificación (la clasificación por precio descendente DENTRO de la categoría; utilice RANGO). Ordene por categoría_id ascendente y rango ascendente.

Cargando editor...
Mostrar pista

PARTICIÓN POR grupos de categoría_id, ORDEN POR precio DESC pedidos dentro del grupo.

Solución disponible después de 3 intentos

Ejercicio de revisión

Ejercicio#sql.m7.l2.e2
Intentos: 0Cargando...

Para cada pedido, muestre id, customer_id,order_at y row_num (ROW_NUMBER progresivo por cliente, ordenado de forma ascendenteorder_at). Ordene por id_cliente y núm_fila.

Cargando editor...
Mostrar pista

ROW_NUMBER siempre es único dentro de la partición.

Solución disponible después de 3 intentos