← 학습 카테고리

Learn

ClickHouse

47개 모듈 · 현재 16번째

ClickHouse 모듈 16/47 clickhouse-learn-16

윈도우 함수와 QUALIFY 절 — 순위 계산 결과를 곧바로 필터링하기

ClickHouse Dictionary 및 QUALIFY 절 공식 문서 종합 (웹 리서치, 2026) — ClickHouse 공식 문서(sql-reference/dictionaries, sql-reference/statements/select/qualify) ClickHouse 공식 문서 QUALIFY clause

이 모듈을 다 읽으면

  • 왜 WHERE/HAVING으로 윈도우 함수 결과를 필터링할 수 없는지 실행 순서 관점에서 설명할 수 있다
  • QUALIFY + ROW_NUMBER()로 그룹별 최신 행만 남기는 중복제거 패턴을 작성할 수 있다

clickhouse-learn-04에서 다룬 ReplacingMergeTree+FINAL의 중복 제거 방식과 대비되는, 쿼리 시점에 즉석으로 그룹별 순위를 매겨 원하는 행만 골라내는 QUALIFY 절과 윈도우 함수 조합을 정리한다.

왜 WHERE/HAVING으로는 윈도우 함수 결과를 못 거르나

SQL 쿼리 실행 순서상 WHERE는 원본 행을 거르는 가장 이른 단계, HAVING은 GROUP BY 집계 이후 단계에서 동작하는데, 윈도우 함수(OVER 절을 쓰는 ROW_NUMBER/RANK 등)는 이 둘보다 더 뒤에 계산된다. 즉 WHERE나 HAVING 시점에는 아직 윈도우 함수의 결과값 자체가 존재하지 않으므로, 그 결과를 조건으로 걸러내려는 시도는 애초에 성립하지 않는다 — QUALIFY는 이 문제를 풀기 위해 윈도우 함수가 계산되고 난 '이후' 단계에서 동작하도록 설계된 절이다.

핵심 포인트

  • 윈도우 함수는 WHERE/HAVING보다 늦게 계산되므로, 그 시점엔 윈도우 함수 결과가 아직 없어 WHERE/HAVING으로 못 거름
  • QUALIFY는 윈도우 함수 계산 '이후' 단계에서 동작하도록 설계된 전용 필터 절

전형적 패턴 — ROW_NUMBER()로 그룹별 최신 행만 남기기

가장 흔한 활용은 SELECT ... QUALIFY ROW_NUMBER() OVER (PARTITION BY 키 ORDER BY 정렬기준 DESC) = 1 형태로, 각 키(예: user_id)별로 정렬 기준(예: 이벤트 시각) 내림차순 1등만 남기는 중복제거다. WHERE는 이 윈도우 계산이 일어나기 전에 원본 행을 먼저 좁히는 데(예: 최근 30일 데이터만) 쓰이고, QUALIFY는 그 다음 단계에서 파티션별 순위를 매긴 결과를 걸러내는 역할을 맡는다 — 여러 컬럼 기준의 복잡한 중복제거 로직에서는 GROUP BY로 억지로 표현하는 것보다 이 패턴이 더 명확하고 성능도 낫다.

핵심 포인트

  • QUALIFY ROW_NUMBER() OVER (PARTITION BY 키 ORDER BY 기준 DESC) = 1 패턴이 그룹별 최신 행 중복제거의 전형적 관용구
  • WHERE는 윈도우 계산 전 원본 행 축소, QUALIFY는 윈도우 계산 후 순위 필터링 — 역할이 서로 다른 단계