Categorias:

Sintaxe de consulta

Junção lateral

Em uma cláusula FROM, a palavra-chave LATERAL permite uma exibição em linha para referenciar colunas de uma expressão de tabela que precede aquela visão em linha.

Uma junção lateral comporta-se mais como uma subconsulta correlata do que como a maioria de JOINs. Uma junção lateral se comporta como se o servidor executasse um loop semelhante ao seguinte:

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

Ao contrário da saída de uma junção não lateral, a saída de uma junção lateral inclui apenas as linhas geradas a partir da exibição em linha. As linhas do lado esquerdo não precisam ser unidas ao lado direito porque as linhas do lado esquerdo já foram levadas em consideração ao serem passadas para a exibição em linha.

Neste tópico:

Sintaxe

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

Esta é uma fonte de linhas, como por exemplo:

  • Uma tabela.

  • Uma exibição.

  • Uma subconsulta.

  • Uma função de tabela.

  • O resultado de uma junção anterior.

inline_view

inline_view pode ser:

  • Uma exibição em linha (uma exibição definida dentro da instrução, e válida apenas pela duração da instrução).

  • Uma subconsulta.

  • Uma função de tabela (ou uma função de tabela interna como FLATTEN ou uma função de tabela definida pelo usuário (UDTF)).

inline_view não pode ser uma tabela.

Notas de uso

  • A exibição em linha após a palavra-chave LATERAL pode referenciar colunas somente da própria exibição em linha e das tabelas à esquerda da exibição em linha na cláusula FROM.

    SELECT *
        FROM table_reference_me, LATERAL (...), table_do_not_reference_me ...
    
    Copy
  • Embora a exibição em linha normalmente faça referência a uma ou mais colunas do left_hand_table_expression, não é necessário fazer isso.

  • Assim como a sintaxe INNER JOIN pode usar a vírgula ou as palavras “INNER JOIN”, uma junção lateral também pode usar a vírgula ou as palavras INNER JOIN.

  • Você não pode especificar a cláusula ON, USING ou NATURAL JOIN em uma função de tabela lateral (diferente de SQL UDTF) e não pode especificar a cláusula ON, USING ou NATURAL JOIN em uma junção lateral externa a uma função de tabela (diferente de SQL UDTF).

    Para obter detalhes, consulte as Notas de Uso no tópico JOIN.

Exemplos

Este exemplo utiliza os dados mostrados abaixo:

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

Exemplo básico

Este exemplo mostra um LATERAL JOIN com uma subconsulta.

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

Exemplo de uso de LATERAL com FLATTEN()

Este exemplo mostra como uma junção lateral pode utilizar a exibição em linha devolvida por FLATTEN:

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

Primeiro, atualizar a tabela de funcionários para incluir os dados ARRAY nos quais FLATTEN pode operar:

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

Segundo, executar uma consulta que utiliza FLATTEN e contém uma referência a uma(s) coluna(s) em uma tabela que a precede:

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

Exemplos que mostram as duas sintaxes de junção

As seguintes instruções SQL são equivalentes e produzem a mesma saída (a saída é mostrada apenas uma vez abaixo). A primeira instrução SQL abaixo usa uma vírgula antes da palavra-chave LATERAL enquanto a segunda instrução SQL usa as palavras-chave 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