1. 시계열 트렌드 분석의 당면 과제: 이전 행/다음 행 데이터를 참조하기
16화에서 우리는 상세 행 구조를 파괴하지 않으면서도 행 간의 경계를 넘어 실시간 시계열 누적치나 요약 통계를 유연하게 산출하는 집계 윈도우 함수의 기초 문법과 비즈니스 대시보드 리팩토링 사례를 살펴보았습니다. 실시간 누적치 가공을 정복하고 나면, 데이터 분석가는 시계열 흐름 속에서 ‘현재 행을 기준으로 바로 전 행의 데이터나 다음 행의 데이터를 가져와 직접 대조하고 증감 추이를 계산해야 하는’ 고난도 비즈니스 요구사항과 마주하게 됩니다.
현업 실무나 마케팅 KPI 분석 과정에서 자주 발생하는 요청은 대개 “이번 달 매출액 옆에 지난달(전월) 매출액을 나열하여 전월 대비 매출 증감률(Month-on-Month, MoM)을 구해달라”거나 “특정 고객의 이번 주 로그인 로그 옆에 다음 로그인 일자를 나열하여 평균 재방문 주기(Retention Interval)를 계산해 달라”는 식의 변동 추이 분석입니다.
일반적인 SQL 문법 규칙은 각 행(Row) 단위로 계산이 독립적으로 수행되기 때문에, 현재 행(Row)에서 이전 행이나 다음 행의 값을 직접 참조하는 것이 구조적으로 까다롭습니다. 이를 무리하게 조인(Self Join)이나 상관 서브쿼리로 구현하려 하면 쿼리가 기하급수적으로 무거워지고 가독성이 무너지는 현상이 발생합니다. 이때 특정 기준 범위 내에서 이전 행의 값을 가져오는 LAG 함수와 다음 행의 값을 가져오는 LEAD 함수는 시계열 분석을 우아하게 해결해 주는 매우 효과적인 대안으로 평가받습니다. 본 연작 시리즈는 대용량 데이터 처리에 활용되는 테라데이터 SQL 환경을 기준으로 이전 행/다음 행 참조 함수의 문법 규칙과 실무 변동 지표 가공 노하우를 설명하겠습니다.
2. LAG와 LEAD 함수의 기본 문법 구조
LAG와 LEAD 함수는 대표적인 분석용 윈도우 함수군에 속하며, 정렬 순서를 명확히 규정해야 전후 관계를 올바르게 인지하기 때문에 뒤에 OVER 절과 정렬 기준을 필수적으로 수반해야 하는 규격을 가집니다.
-- LAG 및 LEAD 함수의 가장 표준적인 문법 구조
SELECT
CUST_NO
, BASE_YM
, PURCHASE_AMT
-- LAG(참조할_칼럼, 몇_단계_이전_행인지, NULL일_때_대체값)
, LAG(PURCHASE_AMT, 1, 0) OVER (
PARTITION BY CUST_NO -- 값을 가져올 기준 방 분할 (생략 가능)
ORDER BY BASE_YM ASC -- 시간의 순서 규정 (필수)
) AS PREV_MONTH_AMT
FROM
TABLE_NAME;
💡 윈도우 구성 요소 및 함수 인자값 문법 규칙
- 첫 번째 인자 (참조할 칼럼): 이전 행이나 다음 행에서 꺼내오고 싶은 대상 칼럼명을 지정합니다.
- 두 번째 인자 (오프셋, Offset): 현재 행을 기준으로 몇 칸 전(또는 몇 칸 뒤)의 데이터를 가져올지 지정합니다. 기본값(Default)은
1로, 한 칸 바로 직전(혹은 직후)의 데이터를 소환하는 데 널리 활용됩니다. - 세 번째 인자 (디폴트값, 생략 가능): 만약 첫 번째 행의 경우, 그 이전 행이 존재하지 않기 때문에 원칙적으로
NULL값이 생성됩니다. 이때 6화에서 배웠던 수동 결측치 예외 처리의 오버헤드를 덜기 위해, 함수 자체 인자에0이나 특정 문자열을 지정하면NULL자리를 지정한 값으로 깔끔하게 자동 대체해 주는 강력한 편의성을 내포하고 있습니다. - ORDER BY (정렬 필수 지정): 데이터가 시간 오름차순(
ASC)으로 나열되어 있어야LAG가 ‘과거의 데이터’를,LEAD가 ‘미래의 데이터’를 정밀하게 추적할 수 있으므로 윈도우 내 정렬 선언은 필수적인 문법 철칙으로 규정되어 있습니다.
3. 현업 비즈니스 사례로 보는 전월 대비 매출 증감률(MoM) 가공 전략
LAG 함수가 실무 비즈니스 장표 분석 과정에서 수많은 라인 조인 연산을 어떻게 단 몇 줄로 경량화하는지, 실제 종합 온라인 커머스 브랜드의 월별 매출 분석 부서에서 자주 발생하는 가상의 시나리오를 통해 짚어보겠습니다.
📊 [실무 사례 예시: 마케팅 기획 팀 최 대리의 브랜드 매출 증감 분석]
패션 브랜드 분석 담당자인 최 대리는 하반기 전략 회의를 앞두고 기획 부서로부터 다음과 같은 변동 추이 데이터 산출 요청을 받았습니다.
- 요청 내용: “각 브랜드별로 2026년 월별 누적 총 매출액을 시간 흐름대로 정렬해 주세요. 단, 브랜드별 트렌드를 정밀 진단할 수 있도록 바로 옆 칼럼에 **’직전 월의 총 매출액’**과 **’전월 대비 매출 증감률(MoM, %)’**을 누락 없이 단 하나의 요약 테이블에 한눈에 보이도록 가공해 주세요.”
최 대리는 복잡한 셀프 조인(Self-Join)을 배제하고, 데이터를 세로로 유지하면서 우측에 전월 실적을 자연스럽게 매칭하기 위해 다음과 같이 LAG() 윈도우 함수를 활용한 최적화 쿼리를 설계하여 실행했습니다.
-- [올바른 예시] LAG 함수와 사칙연산을 융합하여 전월 대비 증감을 산출한 실무 쿼리
SELECT
BRAND_CD -- 브랜드 코드
, BASE_YM -- 분석 기준 년월
, MONTHLY_SALES_AMT -- 당월 매출액
, LAG(MONTHLY_SALES_AMT, 1, 0) OVER (
PARTITION BY BRAND_CD -- 브랜드별로 계산 방 격리
ORDER BY BASE_YM ASC -- 년월 순서대로 정렬하여 흐름 정의
) AS PREV_MONTH_SALES_AMT -- 직전 월 매출액 자동 소환 칼럼
-- 전월 대비 매출 증감액 비율(MoM %) 계산 공식 설계
, CASE
-- 분모가 0이 되는 Zero-Division 에러 방지용 예외 처리 펜싱
WHEN LAG(MONTHLY_SALES_AMT, 1, 0) OVER (PARTITION BY BRAND_CD ORDER BY BASE_YM ASC) = 0
THEN 0
ELSE (MONTHLY_SALES_AMT - LAG(MONTHLY_SALES_AMT, 1, 0) OVER (PARTITION BY BRAND_CD ORDER BY BASE_YM ASC))
/ CAST(LAG(MONTHLY_SALES_AMT, 1, 0) OVER (PARTITION BY BRAND_CD ORDER BY BASE_YM ASC) AS DECIMAL(18,4)) * 100
END AS MOM_GROWTH_PCT -- 전월 대비 증감률(%) 칼럼 생성
FROM
DW_MART.BRAND_MONTHLY_SALES_SUMMARY
WHERE
BASE_YM BETWEEN '202601' AND '202606' -- 2026년 상반기 데이터로 선제 범위 제한
ORDER BY
BRAND_CD ASC
, BASE_YM ASC;
💡 리팩토링된 쿼리의 비즈니스 및 기술적 가치 분석
- Zero-Division 에러 차단 펜싱: 최 대리는 나눗셈 연산 시 첫 달의 전월 데이터가 0인 상태에서 분모로 유입될 때 발생하는 ‘0으로 나누기 오류(Zero-Division)’를 예방하기 위해, 7화에서 배운
CASE WHEN조건문과 결합하여 분모가 0일 경우에는 안전하게 증감률 0%를 반환하도록 예외 처리를 깔끔하게 처리했습니다. - 동일 테이블을 여러 번 Self Join하는 방식보다 일반적으로 더 단순하고 효율적인 실행 계획을 생성할 수 있습니다.
4. 팩트 체크 및 데이터 분석가의 관점 점검 (정렬 조건의 엄격성)
기술적 정확성을 확보하기 위해, 실무에서 시계열 전후 참조 함수를 구사할 때 분석가들이 가장 많이 오해하거나 혼동하는 사실 관계들을 명확히 점검해 보겠습니다.
- LAG나 LEAD를 사용할 때 ORDER BY의 정렬 방향(ASC, DESC)을 바꾸어도 상관없는가?
- 팩트 체크: 결과의 의미가 완전히 정반대로 뒤집히기 때문에 정렬 규칙을 극도로 주의하여 설계해야 합니다.
- 예를 들어
ORDER BY BASE_YM ASC(오름차순) 상태에서LAG함수는 ‘과거의 행(지난달)’을 가져옵니다. 그러나 이를ORDER BY BASE_YM DESC(내림차순)로 정렬 방향을 뒤바꾸면, 쿼리상 명령은LAG라고 적었음에도 실제 시스템은 역순으로 배열된 데이터 흐름을 타게 되므로 결과적으로 다음 달 데이터가 이전 행으로 참조되는 것처럼 해석될 수 있습니다. - 따라서 대부분의 시계열 분석에서는 시간의 흐름과 해석을 일치시키기 위해 ASC를 사용하는 것이 일반적입니다.
- 데이터셋 내에 날짜 공백(빈 월)이 존재할 때도 LAG가 정확히 전월로 연결되는가?
- 팩트 체크: 데이터 상태에 따라 불완전하게 처리될 위험이 있습니다.
LAG(칼럼, 1)은 ‘날짜 기준 한 달 전’을 찾아내는 지능형 날짜 함수가 아니라, 단순하게 정렬된 목록상에서 ‘물리적으로 바로 윗 줄(1행 위)의 값’을 끄집어내는 행 참조 함수입니다. 만약 2월 매출 데이터가 아예 적재되지 않아 데이터셋에 1월 다음 바로 3월 행이 적재되어 있었다면,LAG는 3월 윗 줄인 1월 데이터를 그냥 가져옵니다. - 따라서 데이터셋 자체의 날짜 축이 듬성듬성 비어있는 상태(Sparse Data)라면, 윈도우 함수를 쓰기 전에 날짜 차원 테이블과 외부 조인(
LEFT JOIN)을 수행하여 빈 월자리를 6화 기법인0으로 가득 채워둔 상태에서LAG연산을 적용해야 데이터 왜곡을 확실하게 제어할 수 있습니다.
- 팩트 체크: 데이터 상태에 따라 불완전하게 처리될 위험이 있습니다.
5. 17화 요약 및 실무 시계열 변동 집계 자가 진단 체크리스트
쿼리를 최종 빌드하여 전사 BI 대시보드 스크립트에 안착시키기 전, 연산의 논리적 결점이 없는지 스스로 진단할 수 있는 요약 가이드를 제공합니다.
| 체크포인트 | 발생 가능한 실무 리스크 | 현직 분석가의 권장 대안 및 조치 |
| 분모가 0일 때의 증감률 연산 처리 여부 | 첫 거래 행에서 0으로 나누는 “Zero-Division” 오류로 쿼리 중단 | CASE WHEN [전월금액] = 0 THEN 0 형태로 선제적인 나눗셈 예외 처리 펜싱 |
| 날짜 정렬 기준의 오름차순 정의 여부 | 정렬 방향 혼용 시 LAG와 LEAD의 참조 물리 위치가 반대로 뒤틀림 | 시간의 순서와 직관적인 해석 일치를 위해 윈도우 내부 정렬은 ASC로 일치화 |
| 데이터 행 중간의 유실(비어있는 월) 유무 | 전월이 아닌 전전월 데이터를 전월 실적으로 끄집어와 통계 왜곡 | 조인 전 행 단위를 평탄화하거나 누락 날짜가 발생하지 않도록 기초 정제 선행 |
6. 결론 및 다음 화 예고
이번 17화에서는 별도의 복잡한 서브쿼리나 무거운 셀프 조인 구조를 완전히 걷어내고, 현재 행 옆으로 전월 데이터(LAG)나 미래 데이터(LEAD)를 즉시 소환하여 전월 대비 증감률(MoM) 및 트렌드 분석 지표를 계산해 내는 전후 행 참조 함수의 필수 문법 규칙과 실무 튜닝 사례를 다각도로 점검해 보았습니다. 시계열 데이터의 흐름과 간극을 정밀하게 제어해 내는 윈도우 함수 활용 역량은 기업의 의사결정에 직관적인 트렌드 인사이트를 실시간으로 제시해 주는 훌륭한 밑거름이 됩니다.
지금까지 1화부터 17화에 이르기까지 우리는 이미 구축된 데이터베이스 환경에서 테이블을 조회, 변환, 정렬, 집계하는 모든 영역의 ‘데이터 조회 언어(DQL)’ 과정을 전반적으로 익혔습니다.
이어지는 18화부터는 직접 새로운 데이터를 수용할 그릇(테이블)을 만들고 변경하는 구조 설계자의 영역인 DDL (데이터 정의어) – CREATE, ALTER의 세계로 진입합니다. 실무 분석 과정에서 남에게 권한을 빌리지 않고 나만의 데이터 마트 분석판을 독자적으로 구축하기 위해 필수적으로 사용하는 임시 테이블인 Volatile Table (세션 동안만 유지되는 임시 테이블)과 영구 테이블 생성 문법 구조를 비즈니스 사례와 함께 상세히 파악해 보겠습니다.