- カテゴリ:
ラテラル結合¶
FROM 句では、 LATERAL キーワードを使用すると、インラインビューでそのインラインビューの前にあるテーブル式から列を参照できます。
ラテラル結合は、ほとんどの JOINs よりも相関サブクエリのように動作します。ラテラル結合は、サーバーが次のようなループを実行したかのように動作します。
for each row in left_hand_table LHT:
execute right_hand_subquery RHS using the values from the current row in the LHT
非ラテラル結合の出力とは異なり、ラテラル結合の出力には、インラインビューから生成された行のみが含まれます。左側の行は、インラインビューに渡されることで既に考慮されているため、左側の行を右側に結合する必要はありません。
このトピックの内容:
構文¶
SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
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 ...
通常、インラインビューは
left_hand_table_expression
の列を参照しますが、必ずしもそうする必要はありません。INNER JOIN 構文がコンマまたは単語「INNER JOIN」を使用できるように、ラテラル結合でもコンマまたは単語 INNER JOIN を使用できます。
例¶
この例では、次のデータを使用します。
CREATE TABLE departments (department_id INTEGER, name VARCHAR); CREATE TABLE employees (employee_ID INTEGER, last_name VARCHAR, department_ID INTEGER, project_names ARRAY);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);
基本的な例¶
この例は、サブクエリを持つ 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 | +---------------+-------------+-------------+-----------+---------------+---------------+
FLATTEN()で LATERAL を使用する例¶
この例は、ラテラル結合が FLATTEN
によって返されるインラインビューをどのように使用できるかを示しています。
SELECT * FROM table1, LATERAL FLATTEN(...);
まず、従業員テーブルを更新して、 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;
次に、 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" | +-------------+-----------+-------+----------------------+
両方の結合構文を示す例¶
次の SQL ステートメントは同等であり、同じ出力を生成します(出力は以下に1度だけ示されています)。以下の最初の SQL ステートメントは、キーワード LATERAL の前にコンマを使用していますが、2番目の 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;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 | +---------------+-------------+-------------+-----------+---------------+---------------+