DBAtlas · 데이터베이스 운영 아틀라스

윈도우 함수(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;

윈도우 함수는 행을 그룹화하지 않고(행 수를 줄이지 않고) 각 행에 대해 '윈도우' 범위로 계산한다. PARTITION BY는 윈도우를 나누고, ORDER BY는 정렬한다. Oracle은 이러한 분석 함수를 선도적으로 도입했으며 ROW_NUMBER, RANK, DENSE_RANK, LAG/LEAD, 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은 모든 표준 윈도우 함수를 지원하며, 반복되는 윈도우 정의에 WINDOW ... AS로 이름을 붙일 수 있다. ROWS/RANGE/GROUPS 프레임 정의로 누적 합계, 이동 평균 등을 계산할 수 있다.

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(및 MariaDB 10.2+)은 윈도우 함수를 지원하며, 그 이전에는 사용자 변수나 서브쿼리로 흉내 냈다. ROW_NUMBER, RANK, DENSE_RANK, NTILE, LAG/LEAD, FIRST_VALUE/LAST_VALUE와 집계 함수의 OVER 형식을 사용할 수 있다.

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는 2005부터 순위 윈도우 함수를, 2012부터 프레임 집계와 LAG/LEAD 같은 함수를 지원한다. ROW_NUMBER는 페이징(OFFSET/FETCH와 함께)과 그룹별 상위 N개 행 찾기에 흔히 사용된다.

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

MongoDB 5.0+의 $setWindowFields 단계는 SQL 윈도우 함수에 해당한다. partitionBy와 sortBy로 윈도우를 정의하며 $rank/$denseRank/$documentNumber, $shift(LAG/LEAD), 누적 합계 같은 출력을 생성한다. 이전 버전에서는 $group + 코드로 해결했다.

Redis

# Not applicable: Redis has no window functions.

Redis는 분석용 윈도우 함수를 제공하지 않는다. 정렬된 결과와 순위에는 Sorted Set(ZSET) 구조를 사용한다. ZADD로 점수를 부여하고 ZRANK/ZREVRANK로 순위를, ZRANGE로 범위를 읽는다. 복잡한 분석은 애플리케이션에서 수행한다.

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에는 직접적인 윈도우 함수가 없다. 그룹별 상위 N개 레코드에는 'top_hits' 하위 aggregation을, 이동/누적 계산에는 'derivative', 'cumulative_sum', 'moving_fn' 같은 pipeline aggregation을 사용한다. 정렬과 분할은 terms aggregation으로 수행한다.

DBAtlas에서 열기 →