[SQL 표준] LEFT JOIN LATERAL(또는 LEFT OUTER JOIN LATERAL) 래터럴 조인 사용 방법 예제 총정리
postgreSQL의 LEFT JOIN LATERAL
(또는 LEFT OUTER JOIN LATERAL
)은 일반적인 LEFT OUTER JOIN
과는 유사하지만 중요한 차이점이 있습니다. LATERAL
은 서브쿼리가 왼쪽 테이블의 열을 참조할 수 있도록 허용하는 기능을 제공합니다.
“래터럴” 또는 “래터럴 조인”
(한국어식 표기: 래터럴)
의미상 해석
- 영어 “lateral”은 “옆에 있는”, “측면의” 라는 뜻입니다.
- SQL에서
LATERAL
은 “왼쪽 테이블의 행 옆에 붙어서 실행되는 서브쿼리”라는 의미로 사용됩니다. - 즉, 왼쪽 테이블의 각 행에 대해 옆에서 동적으로 계산한다는 개념입니다.
기억 팁
- Lateral 생각할 때 “각 행 옆에서 돌면서 쿼리 실행” 이렇게 떠올리면 쉽습니다.
LEFT JOIN LATERAL
→ “왼쪽 테이블의 각 행에 대해 옆에서 서브쿼리를 붙여 조인”
핵심 개념 정리
개념 | 설명 |
---|---|
LEFT JOIN / LEFT OUTER JOIN | 기준(왼쪽) 테이블의 모든 행을 유지하고, 오른쪽 테이블에서 조건에 맞는 행을 조인. 조건 불일치 시 NULL . |
LATERAL | 오른쪽 서브쿼리가 왼쪽 테이블의 컬럼을 참조할 수 있게 함. 즉, 행마다 서브쿼리를 실행할 수 있음. |
LEFT JOIN LATERAL | LEFT JOIN 처럼 왼쪽 테이블 기준 행을 모두 유지하면서, 오른쪽에 오는 서브쿼리가 왼쪽 테이블의 값을 사용할 수 있음. |
예제
users
테이블
id | name |
---|---|
1 | Alice |
2 | Bob |
3 | Charlie |
orders
테이블
id | user_id | item | created_at |
---|---|---|---|
1 | 1 | Book | 2023-01-01 |
2 | 1 | Pen | 2023-03-01 |
3 | 2 | Notebook | 2023-02-01 |
예제 : 각 사용자별 가장 최근 주문 1개만 가져오기
일반 LEFT JOIN
은 이렇게 안 됨
SELECT u.*, o.*
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
- 이건 사용자별 모든 주문을 가져옴.
- “가장 최근 주문 1건”을 가져오려면 어려움.
LEFT JOIN LATERAL
사용 예
SELECT u.*, o.*
FROM users u
LEFT JOIN LATERAL (
SELECT *
FROM orders o
WHERE o.user_id = u.id
ORDER BY o.created_at DESC
LIMIT 1
) o ON true;
결과
id | name | id | user_id | item | created_at |
---|---|---|---|---|---|
1 | Alice | 2 | 1 | Pen | 2023-03-01 |
2 | Bob | 3 | 2 | Notebook | 2023-02-01 |
3 | Charlie | NULL | NULL | NULL | NULL |
- Charlie는 주문이 없으므로 오른쪽은
NULL
- LATERAL을 사용해서 각 사용자별로
LIMIT 1
이 동작함
요약 비교
구분 | LEFT JOIN | LEFT JOIN LATERAL |
---|---|---|
서브쿼리에서 왼쪽 테이블 참조 가능? | ❌ 불가능 | ✅ 가능 |
주로 쓰는 목적 | 단순 조인 | 행마다 동적 서브쿼리 실행 |
LIMIT , ORDER BY 와 함께 사용 가능? | ❌ 제한적 | ✅ 가능 |
유지되는 행 | 왼쪽 테이블 기준 모든 행 | 동일 |
래터럴 언제 쓰면 좋은가?
- 왼쪽 테이블의 값을 바탕으로 오른쪽에서 1:N 서브쿼리를 조건부로 제한해야 할 때
- 행마다 최신 기록, 가장 비싼 상품, 관련 정보 등 1건만 조건부로 가져오고 싶을 때
- N+1 쿼리를 방지하며 복잡한 연산을 수행할 때