CodeGym /Cursos /SQL SELF /Errores típicos al usar funciones de ventana

Errores típicos al usar funciones de ventana

SQL SELF
Nivel 30, Lección 4
Disponible

Ahora toca hablar de las complicaciones que pueden surgir cuando trabajas con funciones de ventana. Como siempre, en programación (y en la vida) es mejor aprender de los errores de otros. Vamos a ver los errores más típicos que suelen cometer los principiantes y, a veces, incluso los desarrolladores con experiencia, y aprenderemos a evitarlos.

Error nº1: Uso incorrecto de PARTITION BY

Uno de los fallos más comunes es olvidarse o poner mal el parámetro PARTITION BY, sobre todo si quieres dividir los datos en grupos. Sin él, PostgreSQL va a tratar todas las filas como un solo grupo enorme, y los resultados pueden ser muy diferentes a lo que esperas.

Supón que tienes una tabla sales que contiene datos de ventas:

id region month total
1 North 2023-01 1000
2 South 2023-01 800
3 North 2023-02 1200
4 South 2023-02 900

Quieres calcular la suma acumulada (SUM()) de ventas por mes para cada región. Puedes escribir una consulta así:

SELECT
    region,
    month,
    SUM(total) OVER (ORDER BY month) AS running_total
FROM 
    sales;

Resultado:

region month running_total
North 2023-01 1000
South 2023-01 1800
North 2023-02 3000
South 2023-02 3900

A primera vista parece que todo va bien. Pero el resultado claramente no es el esperado, porque la suma acumulada se calcula para todas las filas juntas, no por región. El problema es que nos olvidamos de poner PARTITION BY region.

Código corregido:

SELECT 
    region,
    month,
    SUM(total) OVER (PARTITION BY region ORDER BY month) AS running_total
FROM 
    sales;

Resultado:

region month running_total
North 2023-01 1000
North 2023-02 2200
South 2023-01 800
South 2023-02 1700

Ahora sí que funciona bien: los datos se agrupan por región y la suma acumulada se calcula por separado para cada una.

Error nº2: Orden incorrecto en ORDER BY

ORDER BY dentro de OVER() controla el orden de las filas dentro de la ventana. Si el orden está mal, los resultados pueden ser raros.

Quieres calcular las sumas acumuladas de ventas, ordenadas por mes descendente. Puedes escribir una consulta así:

SELECT
    month,
    total,
    SUM(total) OVER (ORDER BY month DESC) AS running_total
FROM 
    sales;

Resultado:

month total running_total
2023-02 1200 1200
2023-02 900 2100
2023-01 1000 3100
2023-01 800 3900

Parece que todo está bien, pero fíjate: las filas están agrupadas por mes, pero la suma no se calcula correctamente por el orden descendente. Por eso los resultados son confusos.

Solución: reescribe la consulta usando el orden correcto en ORDER BY:

SELECT
    month,
    total,
    SUM(total) OVER (ORDER BY month ASC) AS running_total
FROM 
    sales;

Error nº3: Usar funciones de ventana sin índices

Las funciones de ventana suelen trabajar con grandes volúmenes de datos, y si no tienes índices en las columnas clave, el rendimiento puede caer en picado.

Ejemplo: tenemos una tabla large_sales con millones de filas y queremos calcular los rangos de ventas:

SELECT
    id,
    total,
    RANK() OVER (ORDER BY total DESC) AS rank
FROM 
    large_sales;

Con pocos datos la consulta va rápido, pero con muchos puede tardar una eternidad.

Solución: añade un índice en la columna que usas en ORDER BY:

CREATE INDEX idx_total ON large_sales(total DESC);

Ahora la consulta irá mucho más rápido.

Error nº4: No entender la ventana definida por ROWS o RANGE

Cuando usas ROWS y RANGE es importante saber cómo calculan la ventana de filas. Si no entiendes bien estas palabras clave, puedes tener resultados inesperados.

Ejemplo: quieres calcular la media móvil de ventas del mes actual y los dos anteriores:

SELECT
    month,
    AVG(total) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM 
    sales;

Si en vez de ROWS pones RANGE:

SELECT
    month,
    AVG(total) OVER (ORDER BY month RANGE BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM 
    sales;

El resultado será diferente, porque RANGE trabaja con rangos de valores, no con un número concreto de filas.

Error nº5: Uso excesivo de funciones de ventana

Usar varias funciones de ventana en una sola consulta puede provocar cálculos duplicados y bajar el rendimiento.

Ejemplo:

SELECT 
    id,
    total,
    SUM(total) OVER (PARTITION BY region) AS region_total,
    SUM(total) OVER (PARTITION BY region) / COUNT(total) OVER (PARTITION BY region) AS region_avg
FROM 
    sales;

Aquí SUM(total) y COUNT(total) se calculan varias veces para cada fila.

Solución: reduce la consulta usando subconsultas o CTE:

WITH cte_region_totals AS (
    SELECT 
        region,
        SUM(total) AS region_total,
        COUNT(total) AS region_count
    FROM 
        sales
    GROUP BY 
        region
)
SELECT 
    s.id,
    s.total,
    t.region_total,
    t.region_total / t.region_count AS region_avg
FROM 
    sales s
JOIN 
    cte_region_totals t ON s.region = t.region;

Consejos para evitar errores

Revisa PARTITION BY y ORDER BY: asegúrate siempre de que la ventana está bien definida.

Pon índices en los datos: sobre todo si usas ordenación (ORDER BY) o filtrado.

Usa CTE para cálculos repetidos: así evitas pasos duplicados.

Mira el plan de ejecución: usa EXPLAIN y EXPLAIN ANALYZE para ver cómo PostgreSQL procesa tu consulta.

Haz pruebas con datos reales: asegúrate de que los resultados son los que esperas y que resuelves bien el problema.

2
Tarea
SQL SELF, nivel 30, lección 4
Bloqueada
Uso de ORDER BY en funciones de ventana
Uso de ORDER BY en funciones de ventana
1
Cuestionario/control
Configuración del marco de ventana, nivel 30, lección 4
No disponible
Configuración del marco de ventana
Configuración del marco de ventana
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION