Desde que o Postgres surgiu com a capacidade de fazer LATERAL
junções, eu tenho lido sobre isso, pois atualmente faço dumps de dados complexos para minha equipe com muitas subconsultas ineficientes que fazem com que a consulta geral leve quatro minutos ou mais.
Entendo que as LATERAL
associações podem me ajudar, mas mesmo depois de ler artigos como este no Heap Analytics, ainda não os entendo.
Qual é o caso de uso para uma LATERAL
associação? Qual é a diferença entre uma LATERAL
junção e uma subconsulta?
sql
postgresql
subquery
lateral-join
jdotjdot
fonte
fonte
apply
é o mesmo que olateral
padrão SQL)Respostas:
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 umaLATERAL
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 naFROM
cláusula. Comounnest()
com vários parâmetros no Postgres 9.4 ou posterior. O manual:Portanto, isso funciona, mas não pode ser facilmente substituído por uma subconsulta:
A vírgula (
,
) naFROM
cláusula é uma notação curta paraCROSS 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
listaVocê também pode usar funções de retorno de conjunto como
unnest()
naSELECT
lista diretamente. Isso costumava exibir um comportamento surpreendente com mais de uma função na mesmaSELECT
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:
Comparação:
dbfiddle para a página 9.6 aqui
dbfiddle para a página 10 aqui
Esclarecer informações erradas
O manual:
Portanto, essas duas consultas são válidas (mesmo que não sejam particularmente úteis):
Enquanto este não é:
É 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.fonte
LATERAL
subconsulta: gis.stackexchange.com/a/230070/7244A diferença entre uma junção não
lateral
e umalateral
junção está em saber se você pode olhar para a linha da tabela à esquerda. Por exemplo:Essa "visão externa" significa que a subconsulta deve ser avaliada mais de uma vez. Afinal,
t1.col1
pode assumir muitos valores.Por outro lado, a subconsulta após uma não
lateral
associação pode ser avaliada uma vez:Como é necessário sem
lateral
, a consulta interna não depende de forma alguma da consulta externa. Umalateral
consulta é um exemplo decorrelated
consulta, devido à sua relação com linhas fora da própria consulta.fonte
select * from table1 left join t2 using (col1)
compara? Não está claro para mim quando uma junção usando / na condição é insuficiente e faria mais sentido usar lateral.Primeiro, a aplicação lateral e cruzada é a mesma coisa . Portanto, você também pode ler sobre o Cross Apply. Desde que foi implementado no SQL Server há muito tempo, você encontrará mais informações sobre ele do que o Lateral.
Segundo, de acordo com meu entendimento , não há nada que você não possa fazer usando subconsulta em vez de usar lateral. Mas:
Considere a seguinte consulta.
Você pode usar lateral nessa condição.
Nesta consulta, você não pode usar a junção normal, devido à cláusula limit. A aplicação lateral ou cruzada pode ser usada quando não há uma condição de junção simples .
Existem mais usos para aplicação lateral ou cruzada, mas essa é a mais comum que encontrei.
fonte
lateral
vez deapply
. Talvez a Microsoft tenha patenteado a sintaxe?lateral
está no padrão SQL, masapply
não está.LEFT JOIN
requer uma condição de junção. Faça aON TRUE
menos que você queira restringir de alguma forma.cross join
ou umaon
condiçãoUma coisa que ninguém apontou é que você pode usar
LATERAL
consultas para aplicar uma função definida pelo usuário em todas as linhas selecionadas.Por exemplo:
Essa é a única maneira de saber como fazer esse tipo de coisa no PostgreSQL.
fonte