Più come una sottoquery correlata
Un LATERAL
join (Postgres 9.3 o successivo) è più simile a una query secondaria correlata , non a una query secondaria semplice. Come sottolineato da Andomar , una funzione o una sottoquery a destra di un LATERAL
join devono essere valutate una volta per ogni riga a sinistra di essa - proprio come una sottoquery correlata - mentre una subquery semplice (espressione di tabella) viene valutata una sola volta . (Il pianificatore di query ha modi per ottimizzare le prestazioni per entrambi.)
Questa risposta correlata presenta esempi di codice per entrambi fianco a fianco, risolvendo lo stesso problema:
Per restituire più di una colonna , un LATERAL
join è in genere più semplice, più pulito e più veloce.
Inoltre, ricorda che l'equivalente di una sottoquery correlata è LEFT JOIN LATERAL ... ON true
:
Leggi il manuale su LATERAL
È più autorevole di qualsiasi cosa stiamo per dare una risposta qui:
Cose che una sottoquery non può fare
Ci sono cose che un LATERAL
join può fare, ma una subquery (correlata) non può (facilmente). Una sottoquery correlata può restituire solo un singolo valore, non più colonne e non più righe, ad eccezione delle chiamate di funzioni nude (che moltiplicano le righe dei risultati se restituiscono più righe). Ma anche determinate funzioni di restituzione del set sono consentite solo nella FROM
clausola. Come unnest()
con più parametri in Postgres 9.4 o successivo. Il manuale:
Questo è consentito solo nella FROM
clausola;
Quindi funziona, ma non può essere facilmente sostituito con una sottoquery:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
La virgola ( ,
) nella FROM
clausola è una breve notazione per CROSS JOIN
.
LATERAL
viene assunto automaticamente per le funzioni della tabella.
Maggiori informazioni sul caso speciale di UNNEST( array_expression [, ... ] )
:
Funzioni di restituzione SELECT
dell'elenco nell'elenco
È inoltre possibile utilizzare le funzioni di set-ritorno come unnest()
nella SELECT
lista direttamente. Questo mostrava comportamenti sorprendenti con più di una di queste funzioni nella stessa SELECT
lista fino a Postgres 9.6. Ma è stato finalmente sterilizzato con Postgres 10 ed è una valida alternativa ora (anche se non standard SQL). Vedere:
Sulla base dell'esempio sopra:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Confronto:
dbfiddle per pg 9.6 qui
dbfiddle per pg 10 qui
Chiarire la disinformazione
Il manuale:
Per i tipi di join INNER
e OUTER
, è necessario specificare una condizione di join, ovvero esattamente uno di NATURAL
, ON
join_condition o USING
( join_column [, ...]). Vedi sotto per il significato.
Perché CROSS JOIN
nessuna di queste clausole può apparire.
Quindi queste due query sono valide (anche se non particolarmente utili):
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;
Mentre questo non lo è:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Ecco perché l' esempio di codice di @ Andomar è corretto ( CROSS JOIN
non richiede una condizione di join) e quello di @ Attila non è valido.
apply
è lo stesso dellateral
dallo standard SQL)