Kategorien:

Abfragesyntax

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
Copy

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> )
...
Copy
left_hand_table_expression

Dies ist eine Quelle für Zeilen wie:

  • Eine Tabelle

  • Eine Ansicht

  • Eine Unterabfrage

  • Eine Tabellenfunktion

  • Das Ergebnis eines früheren Join

inline_view

Die inline_view 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_view 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 ...
    
    Copy
  • Obwohl die Inline-Ansicht normalerweise auf eine oder mehrere Spalten von left_hand_table_expression 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.

  • Sie können die Klauseln ON, USING und NATURAL JOIN nicht in einer lateralen Tabellenfunktion (außer SQL-UDTF) angeben, und Sie können die Klauseln ON, USING und NATURAL JOIN nicht in einem äußeren lateralen Join zu einer Tabellenfunktion (außer SQL-UDTF) angeben.

    Weitere Informationen dazu finden Sie in den Nutzungshinweisen zum Thema JOIN.

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

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

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(...);
Copy

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

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

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