카테고리:

쿼리 구문

래터럴 조인

FROM 절에서 LATERAL 키워드를 사용하면 인라인 뷰가 해당 인라인 뷰에 선행하는 테이블 식의 열을 참조할 수 있습니다.

래터럴 조인은 대부분의 JOIN보다 상관 하위 쿼리처럼 작동합니다. 래터럴 조인은 서버가 다음과 유사한 루프를 실행한 것처럼 작동합니다.

for each row in left_hand_table LHT:
    execute right_hand_subquery RHS using the values from the current row in the LHT
Copy

래터럴이 아닌 조인의 출력과 달리, 래터럴 조인의 출력에는 인라인 뷰에서 생성된 행만 포함됩니다. 왼쪽의 행은 오른쪽과 조인될 필요가 없습니다. 왼쪽의 행은 인라인 뷰로 전달되어 이미 고려되었기 때문입니다.

이 항목의 내용:

구문

SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
Copy
left_hand_table_expression

이는 다음과 같은 행 소스입니다.

  • 테이블.

  • 뷰.

  • 하위 쿼리.

  • 테이블 함수.

  • 이전 조인의 결과입니다.

inline_view

inline_view 는 다음과 같을 수 있습니다:

  • 인라인 뷰(문 내에서 정의되고 문의 기간 동안에만 유효한 뷰).

  • 하위 쿼리.

  • 테이블 함수(FLATTEN 또는 사용자 정의 테이블 함수(UDTF)와 같은 기본 제공 테이블 함수).

inline_view 는 테이블이 될 수 없습니다.

사용법 노트

  • LATERAL 키워드 뒤의 인라인 뷰는 인라인 뷰 자체에서만, 그리고 FROM 절의 인라인 뷰 왼쪽에 있는 테이블에서만 열을 참조할 수 있습니다.

    SELECT *
        FROM table_reference_me, LATERAL (...), table_do_not_reference_me ...
    
    Copy
  • 일반적으로 인라인 뷰는 left_hand_table_expression 의 열을 참조하지만, 반드시 그렇게 할 필요는 없습니다.

  • INNER JOIN 구문이 쉼표나 《INNER JOIN》이라는 단어를 사용할 수 있는 것처럼 래터럴 조인도 쉼표나 INNER JOIN이라는 단어를 사용할 수 있습니다.

  • 측면 테이블 함수(SQL UDTF 제외)에는 ON, USING 또는 NATURAL JOIN 절을 지정할 수 없으며 테이블 함수(SQL UDTF 제외)에 대한 외부 측면 조인에는 ON, USING 또는 NATURAL JOIN 절을 지정할 수 없습니다.

    자세한 내용은 JOIN 항목의 사용법 노트 를 참조하십시오.

이 예에서는 아래 표시된 데이터를 사용합니다.

CREATE TABLE departments (department_id INTEGER, name VARCHAR);
CREATE TABLE employees (employee_ID INTEGER, last_name VARCHAR, 
                        department_ID INTEGER, project_names ARRAY);
Copy
INSERT INTO departments (department_ID, name) VALUES 
    (1, 'Engineering'), 
    (2, 'Support');
INSERT INTO employees (employee_ID, last_name, department_ID) VALUES 
    (101, 'Richards', 1),
    (102, 'Paulson',  1),
    (103, 'Johnson',  2); 
Copy

기본 예

이 예는 하위 쿼리가 있는LATERAL JOIN을 보여줍니다.

SELECT * 
    FROM departments AS d, LATERAL (SELECT * FROM employees AS e WHERE e.department_ID = d.department_ID) AS iv2
    ORDER BY employee_ID;
+---------------+-------------+-------------+-----------+---------------+---------------+
| DEPARTMENT_ID | NAME        | EMPLOYEE_ID | LAST_NAME | DEPARTMENT_ID | PROJECT_NAMES |
|---------------+-------------+-------------+-----------+---------------+---------------|
|             1 | Engineering |         101 | Richards  |             1 | NULL          |
|             1 | Engineering |         102 | Paulson   |             1 | NULL          |
|             2 | Support     |         103 | Johnson   |             2 | NULL          |
+---------------+-------------+-------------+-----------+---------------+---------------+
Copy

FLATTEN()과 함께 LATERAL을 사용하는 예

이 예는 래터럴 조인이 FLATTEN 에서 반환된 인라인 뷰를 어떻게 사용하는지 보여줍니다.

SELECT * FROM table1, LATERAL FLATTEN(...);
Copy

먼저, FLATTEN이 작동할 수 있는 ARRAY 데이터를 포함하도록 직원 테이블을 업데이트합니다.

UPDATE employees SET project_names = ARRAY_CONSTRUCT('Materialized Views', 'UDFs') 
    WHERE employee_ID = 101;
UPDATE employees SET project_names = ARRAY_CONSTRUCT('Materialized Views', 'Lateral Joins')
    WHERE employee_ID = 102;
Copy

둘째, FLATTEN을 사용하고 그 앞에 있는 테이블의 열에 대한 참조를 포함하는 쿼리를 실행합니다.

SELECT emp.employee_ID, emp.last_name, index, value AS project_name
    FROM employees AS emp, LATERAL FLATTEN(INPUT => emp.project_names) AS proj_names
    ORDER BY employee_ID;
+-------------+-----------+-------+----------------------+
| EMPLOYEE_ID | LAST_NAME | INDEX | PROJECT_NAME         |
|-------------+-----------+-------+----------------------|
|         101 | Richards  |     0 | "Materialized Views" |
|         101 | Richards  |     1 | "UDFs"               |
|         102 | Paulson   |     0 | "Materialized Views" |
|         102 | Paulson   |     1 | "Lateral Joins"      |
+-------------+-----------+-------+----------------------+
Copy

두 조인 구문을 모두 표시하는 예

다음 SQL 문은 동일하며 동일 출력을 생성합니다(출력은 아래에 한 번만 표시됨). 아래의 첫 번째 SQL 문은 LATERAL 키워드 앞에 쉼표를 사용하고 두 번째 SQL 문은 INNER JOIN 키워드를 사용합니다.

SELECT * 
    FROM departments AS d, LATERAL (SELECT * FROM employees AS e WHERE e.department_ID = d.department_ID) AS iv2
    ORDER BY employee_ID;
Copy
SELECT * 
    FROM departments AS d INNER JOIN LATERAL (SELECT * FROM employees AS e WHERE e.department_ID = d.department_ID) AS iv2
    ORDER BY employee_ID;
+---------------+-------------+-------------+-----------+---------------+---------------+
| DEPARTMENT_ID | NAME        | EMPLOYEE_ID | LAST_NAME | DEPARTMENT_ID | PROJECT_NAMES |
|---------------+-------------+-------------+-----------+---------------+---------------|
|             1 | Engineering |         101 | Richards  |             1 | NULL          |
|             1 | Engineering |         102 | Paulson   |             1 | NULL          |
|             2 | Support     |         103 | Johnson   |             2 | NULL          |
+---------------+-------------+-------------+-----------+---------------+---------------+
Copy