Mais como uma subconsulta correlacionada
Uma LATERAL
junção (Postgres 9.3 ou posterior) é mais como uma subconsulta correlacionada , não como uma subconsulta simples. Como Andomar apontou , uma função ou subconsulta à direita de uma LATERAL
junção deve ser avaliada uma vez para cada linha restante dela - exatamente como uma subconsulta correlacionada - enquanto uma subconsulta simples (expressão de tabela) é avaliada apenas uma vez . (No entanto, o planejador de consultas tem maneiras de otimizar o desempenho.)
Essa resposta relacionada possui exemplos de código para os dois lados, resolvendo o mesmo problema:
Para retornar mais de uma coluna , uma LATERAL
junção geralmente é mais simples, mais limpa e mais rápida.
Além disso, lembre-se de que o equivalente a uma subconsulta correlacionada é LEFT JOIN LATERAL ... ON true
:
Leia o manual em LATERAL
É mais autoritário do que qualquer coisa que colocaremos em respostas aqui:
Coisas que uma subconsulta não pode fazer
Não são coisas que uma LATERAL
junção pode fazer, mas um (correlacionado) subconsulta 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 das chamadas de função simples (que multiplicam as linhas de resultado se retornarem várias linhas). Mas até certas funções de retorno de conjunto são permitidas apenas na FROM
cláusula. Como unnest()
com vários parâmetros no Postgres 9.4 ou posterior. O manual:
Isso é permitido apenas na FROM
cláusula;
Portanto, isso funciona, mas não pode ser facilmente 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 ( ,
) na FROM
cláusula é uma notação curta para CROSS JOIN
.
LATERAL
é assumido automaticamente para funções da tabela.
Mais sobre o caso especial de UNNEST( array_expression [, ... ] )
:
Funções de retorno de conjunto na SELECT
lista
Você também pode usar funções de retorno de conjunto como unnest()
na SELECT
lista diretamente. Isso costumava exibir um comportamento surpreendente com mais de uma função na mesma SELECT
lista até o Postgres 9.6. Mas finalmente foi higienizado com o Postgres 10 e é uma alternativa válida agora (mesmo que não seja o SQL padrão). Vejo:
Com base no exemplo acima:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Comparação:
dbfiddle para a página 9.6 aqui
dbfiddle para a página 10 aqui
Esclarecer informações erradas
O manual:
Para os tipos INNER
e OUTER
join, uma condição de join deve ser especificada, a saber, exatamente um de NATURAL
, ON
join_condition ou USING
( join_column [, ...]). Veja abaixo o significado.
Pois CROSS 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 do @ Andomar está correto (o CROSS JOIN
não requer uma condição de junção) e o @ do Attila é inválido.
apply
é o mesmo que olateral
padrão SQL)