DBAtlas · Atlas de operações de banco de dados

Funções de janela (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;

As funções de janela calculam sobre uma 'janela' para cada linha sem agrupar as linhas (sem reduzir o número de linhas). PARTITION BY divide a janela, ORDER BY a ordena. O Oracle foi pioneiro nessas funções analíticas e oferece um conjunto rico, incluindo ROW_NUMBER, RANK, DENSE_RANK, LAG/LEAD e 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);

O PostgreSQL suporta todas as funções de janela padrão e permite nomear uma definição de janela repetida com WINDOW ... AS. Com as definições de frame ROWS/RANGE/GROUPS, é possível calcular totais acumulados, médias móveis e 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;

O MySQL 8.0 (e o MariaDB 10.2+) suportam funções de janela; antes disso, eram emuladas com variáveis de usuário ou subconsultas. Estão disponíveis ROW_NUMBER, RANK, DENSE_RANK, NTILE, LAG/LEAD, FIRST_VALUE/LAST_VALUE e a forma OVER das funções de agregação.

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;

O SQL Server suporta funções de janela de ranking desde 2005, e agregações com frame e funções como LAG/LEAD desde 2012. ROW_NUMBER é muito usado para paginação (com OFFSET/FETCH) e para encontrar as N primeiras linhas 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 } } }
  } }
])

O estágio $setWindowFields do MongoDB 5.0+ é o equivalente às funções de janela do SQL: a janela é definida com partitionBy e sortBy, produzindo saídas como $rank/$denseRank/$documentNumber, $shift (LAG/LEAD) e totais acumulados. Em versões mais antigas, isso era resolvido com $group + código.

Redis

# Not applicable: Redis has no window functions.

O Redis não oferece funções analíticas de janela. Para resultados ordenados e ranking, use a estrutura Sorted Set (ZSET): atribua scores com ZADD, leia o ranking com ZRANK/ZREVRANK e intervalos com ZRANGE. Análises complexas são feitas na aplicação.

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 } } } } }
}

O Elasticsearch não tem funções de janela diretas. Para os N primeiros registros por grupo, use uma sub-agregação 'top_hits'; para cálculos móveis/acumulados, use pipeline aggregations como 'derivative', 'cumulative_sum' e 'moving_fn'. Ordenação e particionamento são feitos com uma terms aggregation.

Abrir no DBAtlas →