SQL - LATERAL

Keunjae Song·2020년 6월 12일
1

sql

목록 보기
1/2

최근에 PostgreSQL에서 제공하는 LATERAL에 대해 알게 되면서 이에 대해 정리해보기로 했다.

PostgreSQL을 통해 LATERAL을 적용하는 예제 및 설명은 이 문서가 가장 좋았던 것 같다.
(꼭 한 번 읽어보기 바란다.)

지금까지는 MySQL만 써보아서 MySQL에도 LATERAL이 있을까 걱정했는데 다행히 PostgreSQL의 LATERAL 사용법 그대로 쓸 수 있는 것 같다.

현재까지 이해한 LATERAL

1. join할 때 각 row 별로 for-each문처럼 join할 row를 고를 수 있다.

만약 아래와 같은 쿼리가 있다고 하자.

select *
from base_table t1
left join LATERAL (
  select *
  from base_table t2
  where t2.event_at > t1.event_at
  order by t2.event_at asc
  limit 1
) t2 on true

여기서 event_at 컬럼의 타입을 datetime이라고 가정할 때,
이런 쿼리를 작성하면 이제 t1의 각 row마다 해당 row의 event_at보다 큰 row들 중 가장 가까운 시간의 row를 하나만 골라 join 할 수 있다.

예로, base_table의 event_at이 아래와 같이 저장되어 있다 치자.

id | event_at
1  | 2020-06-01 10:35:00 
2  | 2020-06-01 19:33:00
3  | 2020-06-01 13:33:00

시간 순으로 정렬되어 있지 않은 상태의 테이블이지만, 위 쿼리문을 통해 id가 1인 row(2020-06-01 10:35:00)는 id가 3인 row(2020-06-01 13:33:00)와 join된다.

LATERAL을 쓰면 join을 테이블 단위로 보는 것이 아닌, 어떻게 보면 각 row 단위로 본다고 생각할 수도 있을 것 같다.

이 때문에, LATERAL을 for-each와 비슷하다고 이해하고 있다.

2. 1번을 위해 LATERAL 안에서는 외부 스코프를 볼 수 있다.
이 말이 잘 이해 되지 않을 수 있는데, LATERAL을 쓰지 않는 상황을 생각해보자.

select *
from base_table t1
left join (
  select *
  from base_table t2
  where t2.event_at > t1.event_at
  order by t2.event_at asc
  limit 1
) t2 on t1.id = t2.id

이런 쿼리는 동작할 수 있을까?
아마 left join 다음에 오는 sub-query에서 t1을 찾을 수 없다는 오류 메세지가 뜰 것이다.
sub-query에서는 외부 스코프를 볼 수 없기 때문에 생기는 오류이다.

이 때, LATERAL을 사용하면 외부 스코프를 볼 수 있게 되어 t1을 찾을 수 있고 사용할 수 있게 된다.

for-each에서도 Collection에 대해 iteration을 돌면서 각 element들을 사용할 수 있는 것처럼, LATERAL도 비슷하게 외부 스코프(여기서는 t1)를 볼 수 있게 된다.

0개의 댓글