DBAtlas · Atlas de operaciones de bases de datos

Funciones de ventana (OVER / PARTITION BY)

Oracle

SELECT name, department, salary,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_no,
  RANK()       OVER (PARTITION BY department ORDER BY salary DESC) AS rank_no,
  LAG(salary)    OVER (PARTITION BY department ORDER BY salary)      AS prev_salary
FROM employee;

Las funciones de ventana calculan sobre una 'ventana' para cada fila sin agrupar las filas (sin reducir el número de filas). PARTITION BY divide la ventana y ORDER BY la ordena. Oracle fue pionero en estas funciones analíticas y ofrece un conjunto amplio que incluye ROW_NUMBER, RANK, DENSE_RANK, LAG/LEAD y SUM() OVER.

PostgreSQL

SELECT name, department, salary,
  ROW_NUMBER() OVER w AS row_no,
  RANK()       OVER w AS rank_no,
  LEAD(salary)   OVER w AS next_salary
FROM employee
WINDOW w AS (PARTITION BY department ORDER BY salary DESC);

PostgreSQL admite todas las funciones de ventana estándar y permite nombrar una definición de ventana repetida con WINDOW ... AS. Con las definiciones de marco ROWS/RANGE/GROUPS se pueden calcular totales acumulados, medias móviles y similares.

MySQL

SELECT name, department, salary,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_no,
  DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_no,
  LAG(salary)    OVER (PARTITION BY department ORDER BY salary)      AS prev_salary
FROM employee;

MySQL 8.0 (y MariaDB 10.2+) admiten funciones de ventana; antes se emulaban con variables de usuario o subconsultas. Están disponibles ROW_NUMBER, RANK, DENSE_RANK, NTILE, LAG/LEAD, FIRST_VALUE/LAST_VALUE y la forma OVER de las funciones de agregación.

SQL Server

SELECT name, department, salary,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_no,
  RANK()       OVER (PARTITION BY department ORDER BY salary DESC) AS rank_no,
  SUM(salary)    OVER (PARTITION BY department) AS dept_total
FROM employee;

SQL Server admite funciones de ventana de ranking desde 2005, y agregados con marco y funciones como LAG/LEAD desde 2012. ROW_NUMBER se usa habitualmente para la paginación (con OFFSET/FETCH) y para obtener las N primeras filas por grupo.

MongoDB

// Closest equivalent: $setWindowFields (MongoDB 5.0+)
db.employee.aggregate([
  { $setWindowFields: {
      partitionBy: "$department",
      sortBy: { salary: -1 },
      output: { row_no: { $rank: {} },
                prev_salary: { $shift: { output: "$salary", by: -1 } } }
  } }
])

La etapa $setWindowFields de MongoDB 5.0+ es el equivalente de las funciones de ventana de SQL: la ventana se define con partitionBy y sortBy y produce salidas como $rank/$denseRank/$documentNumber, $shift (LAG/LEAD) y totales acumulados. En versiones anteriores se resolvía con $group + código.

Redis

# Not applicable: Redis has no window functions.

Redis no ofrece funciones analíticas de ventana. Para resultados ordenados y rankings, use la estructura Sorted Set (ZSET): asigne puntuaciones con ZADD, lea la posición con ZRANK/ZREVRANK y los rangos con ZRANGE. La analítica compleja se hace en la aplicación.

Elasticsearch

# Closest equivalent: top_hits and pipeline aggregations
GET employee/_search
{
  "size": 0,
  "aggs": { "dept": { "terms": { "field": "department" },
    "aggs": { "top_paid": { "top_hits": {
      "sort": [ { "salary": "desc" } ], "size": 3 } } } } }
}

Elasticsearch no tiene funciones de ventana directas. Para los N primeros registros por grupo use una subagregación 'top_hits'; para cálculos móviles/acumulados use pipeline aggregations como 'derivative', 'cumulative_sum' y 'moving_fn'. La ordenación y el particionamiento se hacen con una terms aggregation.

Abrir en DBAtlas →