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

윈도우 함수(ROW_NUMBER/RANK/LAG)

Oracle

-- Rank by amount within each city and fetch the previous value:
SELECT city, name, amount,
  ROW_NUMBER() OVER (PARTITION BY city ORDER BY amount DESC) AS row_num,
  RANK()       OVER (PARTITION BY city ORDER BY amount DESC) AS rnk,
  LAG(amount)   OVER (PARTITION BY city ORDER BY created_at)      AS prev_amount
FROM sale;

Oracle은 분석(윈도우) 함수를 선도적으로 도입했으며 ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, SUM/AVG OVER, NTILE, FIRST_VALUE를 완전히 지원한다. OVER 안에서 PARTITION BY는 그룹을, ORDER BY는 순서를, 프레임(ROWS/RANGE BETWEEN)은 슬라이딩 윈도우를 정의한다.

PostgreSQL

-- Window functions with OVER():
SELECT city, name, amount,
  ROW_NUMBER() OVER (PARTITION BY city ORDER BY amount DESC) AS row_num,
  RANK()       OVER (PARTITION BY city ORDER BY amount DESC) AS rnk,
  LAG(amount)   OVER (PARTITION BY city ORDER BY created_at)      AS prev_amount
FROM sale;

PostgreSQL은 표준 SQL 구문으로 윈도우 함수를 완전히 지원한다. ROW_NUMBER/RANK/DENSE_RANK, LAG/LEAD, OVER를 사용한 집계, NTILE, FIRST_VALUE/LAST_VALUE를 사용할 수 있다. 반복되는 윈도우 정의는 WINDOW 절로 이름을 붙여 공유할 수 있다.

MySQL

-- MySQL 8.0+ window functions:
SELECT city, name, amount,
  ROW_NUMBER() OVER (PARTITION BY city ORDER BY amount DESC) AS row_num,
  RANK()       OVER (PARTITION BY city ORDER BY amount DESC) AS rnk,
  LAG(amount)   OVER (PARTITION BY city ORDER BY created_at)      AS prev_amount
FROM sale;

MySQL은 8.0에서 윈도우 함수를 추가했다(MariaDB 10.2+도 지원). ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, NTILE, OVER를 사용한 집계를 사용할 수 있다. 8.0 이전 버전에는 이 함수들이 없으며, 과거에는 사용자 변수로 흉내 냈다.

SQL Server

-- Window functions with OVER():
SELECT city, name, amount,
  ROW_NUMBER() OVER (PARTITION BY city ORDER BY amount DESC) AS row_num,
  RANK()       OVER (PARTITION BY city ORDER BY amount DESC) AS rnk,
  LAG(amount)   OVER (PARTITION BY city ORDER BY created_at)      AS prev_amount
FROM dbo.sale;

SQL Server는 2005(ROW_NUMBER/RANK)와 2012(LAG/LEAD, 프레임, OVER를 사용한 집계)부터 윈도우 함수를 지원한다. PARTITION BY, ORDER BY, ROWS/RANGE 프레임을 모두 사용할 수 있다. 페이징에는 OFFSET/FETCH나 ROW_NUMBER가 일반적이다.

MongoDB

// Window calculations with $setWindowFields:
db.sale.aggregate([
  { $setWindowFields: {
      partitionBy: "$city",
      sortBy: { amount: -1 },
      output: {
        row_num: { $documentNumber: {} },
        rnk: { $rank: {} },
        prev_amount: { $shift: { output: "$amount", by: -1 } }
      }
  } }
])

MongoDB 5.0에서 도입된 $setWindowFields aggregation 단계가 윈도우 함수를 제공한다: $documentNumber(ROW_NUMBER), $rank/$denseRank, $shift(LAG/LEAD), 집계 함수, 슬라이딩 윈도우(window: { documents/range }). partitionBy와 sortBy는 SQL의 PARTITION BY/ORDER BY에 해당한다.

Redis

# Not applicable: there are no SQL-like window functions.

Redis는 키-값 저장소이며 분석용 윈도우 함수가 없다. 정렬된 결과에는 Sorted Set을 사용할 수 있지만(ZADD/ZRANGE로 순위 유사 접근), PARTITION BY/LAG 같은 관계형 윈도우 연산은 애플리케이션 계층에서 수행한다.

Elasticsearch

# Not applicable: there are no SQL-like window functions.
# Closest equivalent: bucket aggregations.
GET sale/_search
{ "size": 0, "aggs": { "by_city": {
  "terms": { "field": "city" },
  "aggs": { "total": { "sum": { "field": "amount" } } } } } }

Elasticsearch는 고전적인 윈도우 함수(ROW_NUMBER/RANK/LAG)를 제공하지 않는다. 그룹화와 정렬은 aggregation 프레임워크로 수행한다. terms aggregation은 PARTITION BY에, top_hits는 상위 레코드에, derivative/serial_diff(pipeline aggregation)는 LAG와 유사한 연속 차이에 가깝다.

DBAtlas에서 열기 →