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 (…)
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)Componentes:
PARTITION BY— define los "grupos" (comoGROUP BY, pero las filas permanecer separado);ORDER BYdentro deOVER(…): 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
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ón | Posiciones |
|---|---|
| CÓDIGOPH0 | 1, 2, 3, 4 (siempre único) |
| CÓDIGOPH1 | 1, 1, 3, 4 (los empates comparten una posición, dejan "espacios") |
| CÓDIGOPH2 | 1, 1, 2, 3 (los empates comparten posición, sin espacios) |
Ejemplo: ranking de productos por categoría
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
-- 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
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.
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
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.
Mostrar pista
ROW_NUMBER siempre es único dentro de la partición.
Solución disponible después de 3 intentos