O que é a LATERAL
participar?
O recurso foi introduzido com o PostgreSQL 9.3. O manual:
Subconsultas que aparecem emFROM
pode ser precedido pela palavra chaveLATERAL
. Isso permite que eles façam referência às colunas fornecidas peloFROM
anterior Itens. (SemLATERAL
, cada subconsulta é avaliada independentemente e, portanto, não pode fazer referência cruzada a nenhum outroFROM
item.)
Funções de tabela que aparecem emFROM
também pode ser precedido pela palavra-chaveLATERAL
, mas para funções a palavra-chave é opcional; os argumentos da função podem conter referências a colunas fornecidas porFROM
precedente itens em qualquer caso.
Exemplos de código básicos são fornecidos lá.
Mais como um correlacionado subconsulta
Um
LATERAL
join é mais como uma subconsulta correlacionada, não uma subconsulta simples, naquelas expressões à direita de um LATERAL
join são avaliados uma vez para cada linha à esquerda - assim como um correlacionado subconsulta - enquanto uma subconsulta simples (expressão de tabela) é avaliada uma vez só. (O planejador de consultas tem maneiras de otimizar o desempenho para ambos.)Resposta relacionada com exemplos de código para ambos lado a lado, resolvendo o mesmo problema:
- Otimize a consulta GROUP BY para recuperar a última linha por usuário
Para retornar mais de uma coluna , um
LATERAL
join é normalmente mais simples, limpo e rápido.Além disso, lembre-se de que o equivalente a uma subconsulta correlacionada é
LEFT JOIN LATERAL ... ON true
:- Chame uma função de retorno de conjunto com um argumento de matriz várias vezes
Coisas que uma subconsulta não pode fazer
Existem há coisas que um
LATERAL
join pode fazer, mas uma subconsulta (correlacionada) não pode (facilmente). Uma subconsulta correlacionada pode retornar apenas um único valor, não várias colunas e nem várias linhas - com exceção de chamadas de função simples (que multiplicam as linhas de resultado se retornarem várias linhas). Mas mesmo certas funções de retorno de conjunto só são permitidas no FROM
cláusula. Como unnest()
com vários parâmetros no Postgres 9.4 ou posterior. O manual:
Isso só é permitido noFROM
cláusula;
Portanto, isso funciona, mas não pode (facilmente) ser substituído por uma subconsulta:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
A vírgula (
,
) no FROM
cláusula é uma notação curta para CROSS JOIN
.LATERAL
é assumido automaticamente para funções de tabela.Sobre o caso especial de
UNNEST( array_expression [, ... ] )
:- Como você declara uma função set-returning para ser permitida apenas na cláusula FROM?
Funções de retorno de set no SELECT
lista
Você também pode usar funções de retorno de conjunto como
unnest()
no SELECT
lista diretamente. Isso costumava exibir um comportamento surpreendente com mais de uma dessas funções no mesmo SELECT
list até o Postgres 9.6. Mas finalmente foi higienizado com o Postgres 10 e é uma alternativa válida agora (mesmo que não seja SQL padrão). Ver:- Qual é o comportamento esperado para várias funções de retorno de conjunto na cláusula SELECT?
Com base no exemplo acima:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Comparação:
dbfiddle para página 9.6 aqui
dbfiddle para página 10 aqui
Esclareça a desinformação
O manual:
Para oINNER
eOUTER
tipos de junção, uma condição de junção deve ser especificada, ou seja, exatamente um deNATURAL
,ON
join_condition ,ouUSING
(join_column [, ...]). Veja abaixo o significado.
ParaCROSS JOIN
, nenhuma dessas cláusulas pode aparecer.
Portanto, essas duas consultas são válidas (mesmo que não sejam particularmente úteis):
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t ON TRUE;
SELECT *
FROM tbl t, LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Enquanto este não é:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
É por isso que o exemplo de código de Andomar está correto (o
CROSS JOIN
não requer uma condição de junção) e Attila