El principio de Pareto surgió de las observaciones de Vilfredo Pareto sobre la propiedad de la tierra en Italia, y más tarde se convirtió en un pilar del control de calidad y la gestión de inventarios a través del trabajo de Joseph Juran. En bases de datos relacionales, esto se traduce en la necesidad del análisis ABC, donde los analistas deben identificar la minoría crítica de registros que impulsan la mayoría del valor comercial sin recurrir a herramientas estadísticas externas.
El problema requiere calcular un porcentaje acumulado de una métrica ordenada de manera descendente en relación con el total absoluto, y luego truncar en el umbral del 80%. Dado que ANSI SQL opera sobre conjuntos en lugar de cursores iterativos, las funciones de ventana proporcionan el mecanismo declarativo. La solución utiliza una suma acumulativa particionada sobre todo el conjunto de resultados, ordenada por el valor en orden descendente, luego se divide por el total general dentro del mismo contexto de fila para derivar un rango percentil.
Críticamente, la especificación del marco ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW asegura una acumulación determinista fila por fila. Si el manejo estricto de empates es necesario—donde todos los registros que comparten el valor límite deben ser incluidos o excluidos como una unidad—RANGE sustituiría a ROWS. La filtración final debe ocurrir en una consulta externa, ya que las funciones de ventana se computan lógicamente después de la cláusula WHERE.
WITH ranked_products AS ( SELECT product_id, product_name, annual_revenue, SUM(annual_revenue) OVER ( ORDER BY annual_revenue DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_revenue, SUM(annual_revenue) OVER () AS total_revenue FROM inventory ), pareto_subset AS ( SELECT product_id, product_name, annual_revenue, CAST(cumulative_revenue AS DECIMAL) / total_revenue AS cumulative_pct FROM ranked_products ) SELECT product_id, product_name, annual_revenue, cumulative_pct FROM pareto_subset WHERE cumulative_pct <= 0.80;
Un minorista nacional de electrónicos enfrentó costos crecientes durante las auditorías trimestrales de inventario, requiriendo el aislamiento de SKU de alto valor que representaban el 80% del capital total del almacén (50 millones de dólares en 40,000 artículos) para priorizar el conteo cíclico.
Solución 1: Extracción de hoja de cálculo involucró a analistas exportando archivos CSV a Excel, ordenando por costo unitario y sumando manualmente hasta alcanzar el umbral. Los pros requerían cero tiempo de desarrollo. Los contras incluían fallos de la aplicación con grandes conjuntos de datos, requisitos de recalculo horarios, y impedían la integración en tiempo real con el sistema de gestión de almacenes.
Solución 2: Cálculo en la capa de aplicación utilizó un script de Python transmitiendo filas y manteniendo un acumulador en ejecución. Los pros ofrecían lógica flexible y fácil depuración. Los contras introdujeron una latencia de red significativa al transferir millones de filas, la ejecución en un solo hilo bloqueando el panel de análisis, y restricciones de memoria en la máquina cliente.
Solución 3: Enfoque basado en conjuntos ANSI SQL implementó la consulta de función de ventana directamente dentro del almacén PostgreSQL. Los pros incluían latencia de nivel de milisegundos, eliminación del movimiento de datos y actualización automática con actualizaciones nocturnas. Los contras requerían conocimiento avanzado de SQL para mantenimiento.
Solución elegida y resultado: La solución 3 se implementó como una vista, revelando que solo el 12% de los SKU representaban el 80% del valor. El alcance de la auditoría se redujo en un 88%, ahorrando 340 horas de trabajo trimestralmente mientras mantenía una cobertura completa del valor material.
¿Cómo afecta la elección entre las especificaciones de marco ROWS y RANGE al umbral del 80% cuando existen valores duplicados?
RANGE trata las filas pares con valores idénticos en ORDER BY como un solo grupo; si el límite del 80% cae dentro de un empate, RANGE incluye todo el grupo, potencialmente superando el 80%. ROWS procesa desplazamientos físicos sin considerar empates, lo que puede dividir una unidad de negocio lógica. Los candidatos a menudo omiten que ANSI SQL permite la sintonización explícita de este comportamiento; para informes financieros, RANGE asegura que los períodos consistentes no se dividan, mientras que ROWS ofrece una mayor granularidad para artículos distintos.
¿Por qué debe realizarse el cálculo del porcentaje acumulativo en una tabla derivada o CTE en lugar de directamente en la cláusula WHERE?
Las funciones de ventana se evalúan lógicamente durante la fase de SELECT, que ocurre después de que la cláusula WHERE filtra las filas. Intentar filtrar en cumulative_revenue / total_revenue <= 0.8 directamente en WHERE produce un error de sintaxis porque el resultado de la ventana aún no se ha materializado. Los candidatos a menudo luchan con el orden de procesamiento lógico de ANSI SQL: FROM → WHERE → GROUP BY → HAVING → WINDOW → SELECT → ORDER BY. La solución requiere anidamiento para calcular la función de ventana en una consulta interna y luego filtrar la columna resultante en una consulta externa.
¿Cómo optimizarías esta consulta si la tabla de inventario contiene miles de millones de filas y se estima que el subconjunto del 80% es muy pequeño?
Los candidatos a menudo pasan por alto el patrón de optimización Top-N. En lugar de calcular una función de ventana sobre toda la tabla, un filtro preliminar usando una subconsulta con DENSE_RANK() o NTILE() puede limitar el cálculo de la ventana a los candidatos más significativos. Alternativamente, aprovechar PARTITION BY si el análisis está segmentado por categoría evita escaneos completos de la tabla. Entender que las funciones de ventana obligan a una operación de ordenación, y que indexar la columna de ingresos en orden descendente puede eliminar el costo de ordenación, es crítico para la escala.