(새 문서: 좋아요! 이번엔 Oracle에서 LATERAL 구문에 대해 초보자도 이해할 수 있게 쉽게 설명드릴게요. LATERAL은 고급 SQL 문법 중 하나지만, 한 번 이해하면 매우 강력하게 쓸 수 있는 기능입니다. ⸻ 1. LATERAL이란? 영문 정의 The LATERAL clause allows a subquery in the FROM clause to reference columns from preceding tables in the same FROM clause. 한글 정의 LATERAL은 FROM 절에 있는 서브쿼리에서 앞에 나오...) |
편집 요약 없음 |
||
(같은 사용자의 중간 판 10개는 보이지 않습니다) | |||
1번째 줄: | 1번째 줄: | ||
=== LATERAL 이란? === | |||
{{요점 | |||
|내용= LATERAL이란? | |||
* (영문)The LATERAL clause allows a subquery in the FROM clause to reference columns from preceding tables in the same FROM clause. | |||
영문 | |||
The LATERAL clause allows a subquery in the FROM clause to reference columns from preceding tables in the same FROM clause. | |||
LATERAL은 FROM 절에 있는 서브쿼리에서 | * (한글) LATERAL은 FROM 절에 있는 서브쿼리에서 같은 레벨에 있는 테이블의 컬럼을 사용할 수 있게 해주는 기능입니다.(oracle12c 이전에는 FROM절에 있는 걑은 레벨의 테이블을 같은 레벨에 있는 서브쿼리에서 사용할수 없었음) | ||
}} | |||
=== 왜 필요한가요? === | |||
# 기존에는 FROM 절의 **서브쿼리(subquery)**가 외부 테이블의 값을 참조할 수 없었어요. | |||
# LATERAL을 쓰면 이 제한을 풀 수 있어, 행 단위로 동적으로 계산하거나 조인할 수 있어요. | |||
=== 기본 문법 === | |||
<source lang=sql> | |||
SELECT ... | SELECT ... | ||
FROM 테이블1 t, | FROM 테이블1 t, | ||
LATERAL ( | LATERAL ( | ||
SELECT ... FROM ... WHERE ... t.컬럼 ... | SELECT ... FROM ... WHERE ... t.컬럼 ... | ||
) | ) A | ||
</source> | |||
Oracle 12c 이상에서는 LATERAL을 쓰지 않고 CROSS APPLY 또는 **OUTER APPLY**를 쓰기도 합니다. Oracle에서 CROSS APPLY = LATERAL. | * Oracle 12c 이상에서는 LATERAL을 쓰지 않고 CROSS APPLY 또는 **OUTER APPLY**를 쓰기도 합니다. | ||
* Oracle에서 CROSS APPLY = LATERAL. | |||
=== 예제 === | |||
예제 테이블 | 예제 테이블 | ||
orders | * orders | ||
{| class="wikitable" | |||
! order_id !! customer_id | |||
|- | |||
| 1 || 100 | |||
|- | |||
| 2 || 200 | |||
|} | |||
* customers | |||
{| class="wikitable" | |||
! customer_id !! name | |||
|- | |||
| 100 || Alice | |||
|- | |||
| 200 || Bob | |||
|- | |||
| 300 || Charlie | |||
|} | |||
목표 | 목표 | ||
64번째 줄: | 64번째 줄: | ||
쿼리 예시 | 쿼리 예시 | ||
<source lang=sql> | |||
SELECT o.order_id, c.name | SELECT o.order_id, c.name | ||
FROM orders o, | FROM orders o, | ||
72번째 줄: | 72번째 줄: | ||
WHERE customers.customer_id = o.customer_id | WHERE customers.customer_id = o.customer_id | ||
) c; | ) c; | ||
</source> | |||
order_id name | * 결과 | ||
1 Alice | {| class="wikitable" | ||
2 Bob | |- | ||
! order_id !! name | |||
|- | |||
| 1 || Alice | |||
|- | |||
| 2 || Bob | |||
|} | |||
90번째 줄: | 95번째 줄: | ||
예제: 각 고객당 최근 주문 1개만 가져오기 | 예제: 각 고객당 최근 주문 1개만 가져오기 | ||
<source lang=sql> | |||
SELECT c.customer_id, c.name, o.order_id | SELECT c.customer_id, c.name, o.order_id | ||
FROM customers c, | FROM customers c, | ||
101번째 줄: | 106번째 줄: | ||
) o; | ) o; | ||
</source> | |||
106번째 줄: | 112번째 줄: | ||
6. LATERAL vs APPLY | 6. LATERAL vs APPLY | ||
{| class="wikitable" | |||
! Oracle 구문 !! 설명 | |||
|- | |||
| LATERAL || Oracle 12c 이상에서 사용 가능 | |||
|- | |||
| CROSS APPLY || LATERAL과 동일 (INNER JOIN) | |||
|- | |||
| OUTER APPLY || LATERAL + OUTER JOIN 느낌 (NULL 허용) | |||
|} | |||
129번째 줄: | 140번째 줄: | ||
보너스: JSON 컬럼 분해에도 유용! | 보너스: JSON 컬럼 분해에도 유용! | ||
<source lang=sql> | |||
SELECT t.id, j.* | SELECT t.id, j.* | ||
FROM my_table t, | FROM my_table t, | ||
135번째 줄: | 146번째 줄: | ||
COLUMNS (name VARCHAR2(100) PATH '$.name', | COLUMNS (name VARCHAR2(100) PATH '$.name', | ||
age NUMBER PATH '$.age')) j; | age NUMBER PATH '$.age')) j; | ||
</source> | |||
위 예제처럼 JSON_TABLE도 LATERAL처럼 동작합니다. | 위 예제처럼 JSON_TABLE도 LATERAL처럼 동작합니다. | ||
140번째 줄: | 152번째 줄: | ||
⸻ | ⸻ | ||
실전 시나리오(예: JSON 배열 쪼개기, 시간대별 계산, 조건별 행 생성 등) |
2025년 5월 22일 (목) 21:51 기준 최신판
LATERAL 이란?
menu_book LATERAL이란?
- (영문)The LATERAL clause allows a subquery in the FROM clause to reference columns from preceding tables in the same FROM clause.
- (한글) LATERAL은 FROM 절에 있는 서브쿼리에서 같은 레벨에 있는 테이블의 컬럼을 사용할 수 있게 해주는 기능입니다.(oracle12c 이전에는 FROM절에 있는 걑은 레벨의 테이블을 같은 레벨에 있는 서브쿼리에서 사용할수 없었음)
왜 필요한가요?
- 기존에는 FROM 절의 **서브쿼리(subquery)**가 외부 테이블의 값을 참조할 수 없었어요.
- LATERAL을 쓰면 이 제한을 풀 수 있어, 행 단위로 동적으로 계산하거나 조인할 수 있어요.
기본 문법
SELECT ... FROM 테이블1 t, LATERAL ( SELECT ... FROM ... WHERE ... t.컬럼 ... ) A
- Oracle 12c 이상에서는 LATERAL을 쓰지 않고 CROSS APPLY 또는 **OUTER APPLY**를 쓰기도 합니다.
- Oracle에서 CROSS APPLY = LATERAL.
예제
예제 테이블
- orders
order_id | customer_id |
---|---|
1 | 100 |
2 | 200 |
- customers
customer_id | name |
---|---|
100 | Alice |
200 | Bob |
300 | Charlie |
목표
orders 테이블에서 각 주문에 해당하는 고객 정보를 바로 옆에서 가져오기 (JOIN도 가능하지만, LATERAL은 더 유연한 활용이 가능)
⸻
쿼리 예시
SELECT o.order_id, c.name FROM orders o, LATERAL ( SELECT name FROM customers WHERE customers.customer_id = o.customer_id ) c;
- 결과
order_id | name |
---|---|
1 | Alice |
2 | Bob |
⸻
5. 동적으로 N개만 가져오기 (Top-N per group)
예제: 각 고객당 최근 주문 1개만 가져오기
SELECT c.customer_id, c.name, o.order_id FROM customers c, LATERAL ( SELECT order_id FROM orders WHERE orders.customer_id = c.customer_id ORDER BY order_id DESC FETCH FIRST 1 ROW ONLY ) o;
⸻
6. LATERAL vs APPLY
Oracle 구문 | 설명 |
---|---|
LATERAL | Oracle 12c 이상에서 사용 가능 |
CROSS APPLY | LATERAL과 동일 (INNER JOIN) |
OUTER APPLY | LATERAL + OUTER JOIN 느낌 (NULL 허용) |
⸻
7. 요약
항목 내용 목적 FROM 서브쿼리에서 앞의 테이블 값을 참조하고 싶을 때 사용 장점 각 행별로 동적인 서브쿼리 실행 가능 주 사용처 Top-N per group, JSON 파싱, 동적 컬럼 처리 등 필요 조건 Oracle 12c 이상
⸻
보너스: JSON 컬럼 분해에도 유용!
SELECT t.id, j.* FROM my_table t, JSON_TABLE(t.json_col, '$[*]' COLUMNS (name VARCHAR2(100) PATH '$.name', age NUMBER PATH '$.age')) j;
위 예제처럼 JSON_TABLE도 LATERAL처럼 동작합니다.
⸻
실전 시나리오(예: JSON 배열 쪼개기, 시간대별 계산, 조건별 행 생성 등)