El cálculo de totales acumulativos y sumas en curso se ha resuelto tradicionalmente en SQL a través de funciones de ventana (por ejemplo, SUM() OVER(ORDER BY ...)), sin embargo, en versiones anteriores o simplificadas de las bases de datos solo se dispone de subconsultas y agrupaciones. Históricamente, los arquitectos de bases de datos buscaban soluciones alternativas hasta la llegada del estándar SQL:2003 que soporta funciones de ventana.
Problema — En ausencia de funciones de ventana, es necesario calcular explícitamente la suma de todos los valores anteriores para cada fila, lo que resulta en consultas anidadas O(N^2) en conjuntos de datos grandes, a menos que se apliquen trucos.
Solución:
Normalmente se utilizan subconsultas correlacionadas o tablas temporales con actualización de valores:
Ejemplo de código:
-- Suma acumulativa con subconsulta correlacionada SELECT t1.id, t1.amount, ( SELECT SUM(t2.amount) FROM transactions t2 WHERE t2.id <= t1.id ) AS running_total FROM transactions t1 ORDER BY t1.id; -- A través de una tabla temporal con actualización manual de valores CREATE TEMPORARY TABLE temp_running (id INT, amount INT, running_total INT); -- Se recorre las filas mediante código externo (por ejemplo, pl/pgsql), añadiendo secuencialmente la suma
Características clave:
¿Garantiza la ordenación ORDER BY en una subconsulta correlacionada?
No — la subconsulta no necesariamente afecta el resultado mismo. La ordenación del conjunto final siempre se establece externamente en la consulta principal: el resultado depende solo de la filtración por WHERE.
¿Se puede paralelizar el cálculo de la suma acumulativa en este enfoque?
No — la secuencia es muy importante, especialmente al calcular en función de filas anteriores, por lo que la simple paralelización no es posible en SQL normal.
¿Por qué es tan lenta la subconsulta correlacionada con un gran número de filas?
Porque para cada fila se vuelve a calcular la suma sobre el conjunto de filas anteriores. Esto lleva a O(N^2) operaciones. Con un conjunto de 100 mil filas, esto ya puede tardar minutos o incluso horas.
Un analista calculó la recaudación acumulativa diaria por fecha a través de una subconsulta correlacionada, y de forma periódica, aparecían ids eliminados (huecos) en la tabla. La suma total tenía caídas abruptas y dependía no de la fecha, sino del orden de los ids.
Pros:
Contras:
Un ingeniero llevó el procesamiento de la suma acumulativa a un script ETL (Python/pandas), y luego cargó los valores finales en una tabla separada, sincronizando solo las novedades. Los totales siempre están acordes a la fecha, el código funciona rápido y con millones de registros.
Pros:
Contras: