Più come una sottoquery correlata
Un LATERALjoin (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 LATERALjoin 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 LATERALjoin è 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 LATERALjoin 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 FROMclausola. Come unnest()con più parametri in Postgres 9.4 o successivo. Il manuale:
Questo è consentito solo nella FROMclausola;
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 FROMclausola è una breve notazione per CROSS JOIN.
LATERALviene assunto automaticamente per le funzioni della tabella.
Maggiori informazioni sul caso speciale di UNNEST( array_expression [, ... ] ):
Funzioni di restituzione SELECTdell'elenco nell'elenco
È inoltre possibile utilizzare le funzioni di set-ritorno come unnest()nella SELECTlista direttamente. Questo mostrava comportamenti sorprendenti con più di una di queste funzioni nella stessa SELECTlista 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 INNERe 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 JOINnessuna 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 JOINnon richiede una condizione di join) e quello di @ Attila non è valido.
applyè lo stesso dellateraldallo standard SQL)