윈도우 함수(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와 유사한 연속 차이에 가깝다.