호테의 노트에 오신 것을 환영합니다 🙌

Tableau와 Salesforce, Python과 SQL 등 데이터의 전반적인 것들을 다루는 기술 블로그입니다.

SQL

SQL에서의 LATERAL JOIN

Hote's Note 2025. 6. 26. 10:34

SQL을 사용하다 보면 하위 쿼리(Subquery)인라인 뷰 안에서 메인 쿼리의 값을 활용하고 싶은 경우가 종종 있습니다. 이런 상황에서 강력한 기능을 제공하는 것이 바로 LATERAL JOIN입니다.

이번 글에서는 LATERAL JOIN의 개념, 사용법, 실무 예시, 주의점까지 하나하나 정리해드릴게요.

1.  LATERAL JOIN이란?

SQL에서 일반적으로 하위 쿼리(Subquery)외부 쿼리의 컬럼을 참조할 수 없습니다. 그러나 LATERAL 키워드를 사용하면 하위 쿼리에서 외부 쿼리의 컬럼을 사용할 수 있게 됩니다.

즉, LATERAL JOIN하위 쿼리를 외부 쿼리의 각 행마다 실행하며, 외부 쿼리의 값을 내부에서 참조할 수 있도록 해주는 기능입니다.

💡 쉽게 말하면, LATERAL은 SQL에서도 “행 단위 반복 처리”가 가능하게 만들어주는 도구입니다.

2. 기본 문법

SELECT ...
FROM outer_table
JOIN LATERAL (
    SELECT ...
    FROM inner_table
    WHERE inner_table.col = outer_table.col
) AS alias
  • outer_table: 메인 쿼리 테이블
  • inner_table: LATERAL로 연결할 서브쿼리 대상 테이블
  • outer_table.col을 서브쿼리 안에서 직접 사용할 수 있음

3.  왜 필요한가요?

일반적인 JOIN이나 서브쿼리로는 다음 같은 작업이 어렵습니다:

  • 외부 쿼리에서 들어온 값에 따라 서브쿼리의 결과가 달라져야 할 때
  • 테이블 함수(table function)나 JSON array, CSV column parsing 등 row-by-row 처리가 필요한 경우
  • PostgreSQL 등에서는 LATERAL을 사용해 유연한 쿼리 구성이 가능함

4. 실무 예제

예제 1: 고객별 최근 주문 1건 가져오기

SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
JOIN LATERAL (
    SELECT *
    FROM orders o
    WHERE o.customer_id = c.customer_id
    ORDER BY o.order_date DESC
    LIMIT 1
) o ON true;

📌 해설:

  • customers 테이블의 각 고객에 대해,
  • 해당 고객의 orders 중 가장 최근 1건을 가져오는 쿼리입니다.
  • 일반 JOIN으로는 이런 쿼리를 효율적으로 작성하기 어렵습니다.

예제 2: JSON 배열 파싱 (PostgreSQL)

SELECT u.id, j.value AS tag
FROM users u,
LATERAL json_array_elements_text(u.tags) AS j;

📌 해설:

  • users.tags 컬럼이 JSON 배열인 경우,
  • json_array_elements_text()로 각 값을 분리해 행으로 만듭니다.
  • LATERAL이 있어야 u.tags를 내부에서 참조할 수 있습니다.

5.  주의할 점

  • LATERAL JOIN은 모든 DBMS에서 지원되는 기능은 아닙니다.
    • PostgreSQL, Oracle 12c+, SQL Server 2022+, MySQL 8.0+ 등은 지원합니다.
    • MySQL 5.xMS SQL Server 구버전에서는 사용할 수 없습니다.
  • MySQL에서는 LATERAL 없이도 CROSS APPLY, OUTER APPLY (SQL Server 스타일)를 사용하면 유사한 효과를 낼 수 있습니다.
  • 성능 이슈가 있을 수 있으므로 인덱싱 및 실행계획 확인이 필요합니다.

6.  언제 사용해야 할까?

상황 LATERAL JOIN 적합 여부
외부 쿼리의 컬럼을 서브쿼리에서 쓰고 싶다 ✅ Yes
테이블 함수나 JSON 처리, 동적 필터링 필요 ✅ Yes
단순 조인 또는 조건만 필요한 경우 ❌ No (기존 JOIN 사용 권장)