LAG

LAG (이전 행 값 접근)

테이블을 자기 자신과 조인하지 않고도 동일한 결과 집합에서 이전 행의 데이터에 접근해요.

출처: Snowflake SQL Reference - LAG

본문

구문 (Syntax)

LAG( <expr> [, <offset>, <default>] ) [ { IGNORE | RESPECT } NULLS ]
    OVER ( [ PARTITION BY <expr1> ] ORDER BY <expr2> [ { ASC | DESC } ] [ NULLS { FIRST | LAST } ] )

인자 (Arguments)

expr

지정된 offset을 기준으로 반환할 표현식이에요.

offset

현재 행에서 값 하나를 가져올 만큼 뒤로 이동할 행 수예요. 예를 들어 offset이 2이면 2행 간격으로 expr 값을 반환해요. 음수 offset을 설정하면 LEAD 함수를 사용한 것과 같은 효과가 있다는 점에 유의하세요. 기본값은 1이에요.

default

offset이 창(window) 범위를 벗어날 때 반환할 표현식이에요. expr과 타입이 호환되는 모든 표현식을 지원해요. 기본값은 NULL이에요.

{ IGNORE | RESPECT } NULLS

expr에 NULL 값이 있을 때 NULL 값을 무시할지 존중할지 여부예요: IGNORE NULLS는 offset 행을 셀 때 표현식이 NULL로 평가되는 행을 제외해요. RESPECT NULLS는 offset 행을 셀 때 표현식이 NULL로 평가되는 행을 포함해요. 기본값: RESPECT NULLS.

사용 참고 사항 (Usage notes)

PARTITION BY 절은 FROM 절이 만든 결과 집합을 함수가 적용되는 파티션들로 나눠요. 자세한 내용은 Window function syntax and usage를 참고하세요.

ORDER BY 절은 각 파티션 내부의 데이터를 정렬해요.

예시 (Examples)

테이블을 만들고 데이터를 로드해요:

CREATE OR REPLACE TABLE sales (
  emp_id INTEGER,
  year INTEGER,
  revenue DECIMAL(10,2));
INSERT INTO sales VALUES
  (0, 2010, 1000),
  (0, 2011, 1500),
  (0, 2012, 500),
  (0, 2013, 750);

INSERT INTO sales VALUES
  (1, 2010, 10000),
  (1, 2011, 12500),
  (1, 2012, 15000),
  (1, 2013, 20000);

INSERT INTO sales VALUES
  (2, 2012, 500),
  (2, 2013, 800);

이 쿼리는 올해 수익과 전년도 수익의 차이를 보여줘요:

SELECT emp_id, year, revenue,
       revenue - LAG(revenue, 1, 0) OVER (PARTITION BY emp_id ORDER BY year) AS diff_to_prev
  FROM sales
  ORDER BY emp_id, year;
+--------+------+----------+--------------+
| EMP_ID | YEAR |  REVENUE | DIFF_TO_PREV |
|--------+------+----------+--------------|
|      0 | 2010 |  1000.00 |      1000.00 |
|      0 | 2011 |  1500.00 |       500.00 |
|      0 | 2012 |   500.00 |     -1000.00 |
|      0 | 2013 |   750.00 |       250.00 |
|      1 | 2010 | 10000.00 |     10000.00 |
|      1 | 2011 | 12500.00 |      2500.00 |
|      1 | 2012 | 15000.00 |      2500.00 |
|      1 | 2013 | 20000.00 |      5000.00 |
|      2 | 2012 |   500.00 |       500.00 |
|      2 | 2013 |   800.00 |       300.00 |
+--------+------+----------+--------------+

다른 테이블을 만들고 데이터를 로드해요:

CREATE OR REPLACE TABLE t1 (
  col_1 NUMBER,
  col_2 NUMBER);
INSERT INTO t1 VALUES
  (1, 5),
  (2, 4),
  (3, NULL),
  (4, 2),
  (5, NULL),
  (6, NULL),
  (7, 6);

이 쿼리는 IGNORE NULLS 절이 출력에 어떤 영향을 주는지 보여줘요. 앞선 행에 NULL이 있었더라도 첫 행을 제외한 모든 행에는 비-NULL 값이 들어 있어요. 앞선 행이 NULL이면 현재 행은 가장 최근의 비-NULL 값을 사용해요.

SELECT col_1, col_2,
       LAG(col_2) IGNORE NULLS OVER (ORDER BY col_1)
  FROM t1
  ORDER BY col_1;
+-------+-------+-----------------------------------------------+
| COL_1 | COL_2 | LAG(COL_2) IGNORE NULLS OVER (ORDER BY COL_1) |
|-------+-------+-----------------------------------------------|
|     1 |     5 |                                          NULL |
|     2 |     4 |                                             5 |
|     3 |  NULL |                                             4 |
|     4 |     2 |                                             4 |
|     5 |  NULL |                                             2 |
|     6 |  NULL |                                             2 |
|     7 |     6 |                                             2 |
+-------+-------+-----------------------------------------------+

더 알아보기 (Learn more)