Over 집계
Over 집계 (Over Aggregation)
OVER 집계는 정렬된 행 범위에 대해 모든 입력 행에 대한 집계 값을 계산합니다. GROUP BY 집계와 달리 OVER 집계는 각 그룹의 결과 행 수를 한 행으로 줄이지 않습니다. 대신 각 입력 행에 대해 집계 값을 생성합니다.
출처: 문서
본문
이 절은 Batch 와 Streaming 모드에서 모두 지원됩니다.
OVER 집계는 정렬된 행 범위에 대해 모든 입력 행에 대한 집계 값을 계산합니다. GROUP BY 집계와 달리 OVER 집계는 각 그룹의 결과 행 수를 한 행으로 줄이지 않습니다. 대신 각 입력 행에 대해 집계 값을 생성합니다.
다음 쿼리는 각 주문에 대해, 현재 주문 1시간 전에 받은 같은 제품의 모든 주문 금액의 합을 계산합니다:
SELECT order_id, order_time, amount,
SUM(amount) OVER (
PARTITION BY product
ORDER BY order_time
RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW
) AS one_hour_prod_amount_sum
FROM Orders
OVER 윈도우의 문법은 아래에 요약되어 있습니다:
SELECT
agg_func(agg_col) OVER (
[PARTITION BY col1[, col2, ...]]
ORDER BY time_col|non_time_col
range_definition|row_definition),
...
FROM ...
SELECT 절에서 여러 OVER 윈도우 집계를 정의할 수 있습니다. 그러나 스트리밍 쿼리의 경우 모든 집계의 OVER 윈도우는 현재 제한 사항으로 인해 동일해야 합니다.
ORDER BY
OVER 윈도우는 정렬된 행 시퀀스에 대해 정의됩니다. 테이블은 고유한 순서가 없으므로 ORDER BY 절은 필수입니다. 스트리밍 쿼리의 경우 Flink 는 현재 오름차순 시간 속성 또는 오름차순 비시간 속성으로 정의된 OVER 윈도우만 지원합니다. 추가 정렬은 지원되지 않습니다.
PARTITION BY
OVER 윈도우는 파티셔닝된 테이블에 정의할 수 있습니다. PARTITION BY 절이 있으면 집계는 각 입력 행에 대해 해당 행이 속한 파티션의 행들에 대해서만 계산됩니다.
범위 정의 (Range Definitions)
범위 정의는 집계에 포함할 행 수를 지정합니다. 범위는 하한과 상한을 정의하는 BETWEEN 절로 정의됩니다. 이 경계 사이의 모든 행이 집계에 포함됩니다. Flink 는 상한으로 CURRENT ROW 만 지원합니다.
범위를 정의하는 옵션은 ROWS 간격과 RANGE 간격 두 가지입니다.
RANGE 간격
RANGE 간격은 ORDER BY 열의 값에 정의되며, (Flink 의 경우) 시간 또는 비시간 속성입니다.
다음 RANGE 간격은 현재 행보다 최대 30분 작은 시간 속성을 가진 모든 행이 집계에 포함됨을 정의합니다:
RANGE BETWEEN INTERVAL '30' MINUTE PRECEDING AND CURRENT ROW
다음 RANGE 간격은 현재 행보다 앞선 무한 행(unbounded rows)의 비시간 속성을 가진 모든 행이 집계에 포함됨을 정의합니다:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
ROW 간격
ROWS 간격은 개수 기반 간격입니다. 집계에 포함될 행 수를 정확히 정의합니다. 다음 ROWS 간격은 현재 행 앞의 10개 행과 현재 행(총 11개 행)이 집계에 포함됨을 정의합니다:
ROWS BETWEEN 10 PRECEDING AND CURRENT ROW
WINDOW
WINDOW 절은 SELECT 절 밖에서 OVER 윈도우를 정의하는 데 사용할 수 있습니다. 쿼리를 더 읽기 쉽게 만들고 여러 집계에 윈도우 정의를 재사용할 수 있게 합니다:
SELECT order_id, order_time, amount,
SUM(amount) OVER w AS sum_amount,
AVG(amount) OVER w AS avg_amount
FROM Orders
WINDOW w AS (
PARTITION BY product
ORDER BY order_time
RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW)