Seitliche Verknüpfung (Lateral Join)

In einer FROM-Klausel ermöglicht das LATERAL-Schlüsselwort einer Inline-Ansicht, auf Spalten aus einem Tabellenausdruck zu verweisen, der dieser Inline-Ansicht vorausgeht.

Ein lateraler Join verhält sich eher wie eine korrelierte Unterabfrage als wie die meisten JOINs. Ein lateraler Join verhält sich so, als hätte der Server eine Schleife ausgeführt, die der folgenden ähnelt:

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

Im Gegensatz zur Ausgabe eines nicht lateralen Joins enthält die Ausgabe eines lateralen Joins nur die Zeilen, die aus der Inline-Ansicht generiert wurden. Die Zeilen auf der linken Seite müssen nicht mit der rechten Seite verknüpft werden, da die Zeilen auf der linken Seite bereits bei der Übergabe in die Inline-Ansicht berücksichtigt wurden.

Unter diesem Thema:

Syntax

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

linker_Tabellenausdruck

Dies ist eine Quelle für Zeilen wie:

  • Eine Tabelle

  • Eine Ansicht

  • Eine Unterabfrage

  • Eine Tabellenfunktion

  • Das Ergebnis eines früheren Join

Inline-Ansicht

Die Inline-Ansicht kann sein:

  • Eine Inline-Ansicht (eine in der Anweisung definierte Ansicht, die nur für die Dauer der Anweisung gültig ist)

  • Eine Unterabfrage

  • Eine Tabellenfunktion (entweder eine integrierte Tabellenfunktion wie FLATTEN oder eine benutzerdefinierte Tabellenfunktion (UDTF))

Die Inline-Ansicht kann keine Tabelle sein.

Nutzungshinweise

  • Die Inline-Ansicht nach dem Schlüsselwort LATERAL kann nur auf Spalten in der Inline-Ansicht selbst und in Tabellen links von der Inline-Ansicht in der FROM-Klausel verweisen.

    SELECT *
        FROM table_reference_me, LATERAL (...), table_do_not_reference_me ...
    
  • Obwohl die Inline-Ansicht normalerweise auf eine oder mehrere Spalten von linker_Tabellenausdruck verweist, ist dies nicht erforderlich.

  • So wie bei der INNER JOIN-Syntax entweder das Komma oder die Wörter „INNER JOIN“ verwendet werden können, können bei einem lateralen Join ebenfalls das Komma oder die Wörter INNER JOIN verwendet werden.

Beispiele

In diesem Beispiel werden die folgenden Daten verwendet:

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); 

Grundlegendes Beispiel:

Dieses Beispiel zeigt ein LATERAL JOIN mit einer Unterabfrage.

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          |
+---------------+-------------+-------------+-----------+---------------+---------------+

Beispiel für die Verwendung von LATERAL mit FLATTEN()

Dieses Beispiel zeigt, wie ein lateraler Join die von FLATTEN zurückgegebene Inline-Ansicht verwenden kann:

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

Aktualisieren Sie zunächst die Mitarbeitertabelle mit ARRAY-Daten, auf die FLATTEN angewendet werden kann:

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;

Führen Sie anschließend eine Abfrage aus, die FLATTEN verwendet und einen Verweis auf eine oder mehrere Spalten einer vorhergehenden Tabelle enthält:

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"      |
+-------------+-----------+-------+----------------------+

Beispiele für beide Join-Varianten

Die folgenden SQL-Anweisungen sind äquivalent und erzeugen dieselbe Ausgabe (die Ausgabe wird unten nur einmal angezeigt). Die erste SQL-Anweisung unten verwendet ein Komma vor dem Schlüsselwort LATERAL, während die zweite SQL-Anweisung die Schlüsselwörter INNER JOIN verwendet.

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          |
+---------------+-------------+-------------+-----------+---------------+---------------+