Che cosa è un LATERAL
partecipare?
La funzionalità è stata introdotta con PostgreSQL 9.3. Il manuale:
Sottoquery che appaiono in FROM
può essere preceduto dalla parola chiaveLATERAL
. Ciò consente loro di fare riferimento alle colonne fornite da FROM
precedente Oggetti. (Senza LATERAL
, ogni sottoquery viene valutata in modo indipendente e quindi non può fare riferimento a nessun altro FROM
elemento.)
Funzioni della tabella che appaiono in FROM
può anche essere preceduto dalla parola chiave LATERAL
, ma per le funzioni la parola chiave è facoltativa; gli argomenti della funzione possono contenere riferimenti a colonne fornite da FROM
in ogni caso.
Qui vengono forniti esempi di codice di base.
Più simile a una correlata sottoquery
Un LATERAL
join è più simile a una sottoquery correlata, non a una semplice sottoquery, in quanto espressioni a destra di un LATERAL
join vengono valutati una volta per ogni riga rimasta, proprio come un correlato subquery - mentre una semplice sottoquery (espressione di tabella) viene valutata una volta solo. (Il pianificatore di query ha modi per ottimizzare le prestazioni per entrambi, tuttavia.)
Risposta correlata con esempi di codice per entrambi fianco a fianco, risolvendo lo stesso problema:
- Ottimizza la query GROUP BY per recuperare l'ultima riga per utente
Per restituire più di una colonna , un LATERAL
join è in genere più semplice, pulito e veloce.
Ricorda inoltre che l'equivalente di una sottoquery correlata è LEFT JOIN LATERAL ... ON true
:
- Richiama più volte una funzione di restituzione di set con un argomento array
Cose che una sottoquery non può fare
Ci ci sono cose che un LATERAL
join può fare, ma una sottoquery (correlata) non può (facilmente). Una sottoquery correlata può restituire solo un singolo valore, non più colonne e non più righe, ad eccezione delle semplici chiamate di funzione (che moltiplicano le righe dei risultati se restituiscono più righe). Ma anche alcune funzioni di restituzione dei set sono consentite solo in FROM
clausola. Come unnest()
con più parametri in Postgres 9.4 o versioni successive. Il manuale:
Questo è consentito solo nel FROM
clausola;
Quindi funziona, ma non può (facilmente) essere sostituito con una sottoquery:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
La virgola (,
) nel FROM
la clausola è una notazione breve per CROSS JOIN
.LATERAL
viene assunto automaticamente per le funzioni di tabella.
Informazioni sul caso speciale di UNNEST( array_expression [, ... ] )
:
- Come si fa a dichiarare che una funzione di ritorno dell'insieme è consentita solo nella clausola FROM?
Funzioni di ritorno degli insiemi nel SELECT
elenco
Puoi anche utilizzare funzioni di restituzione di set come unnest()
nel SELECT
elencare direttamente. Questo mostrava un comportamento sorprendente con più di una di queste funzioni nello stesso SELECT
elencare fino a Postgres 9.6. Ma finalmente è stato sanificato con Postgres 10 ed è ora una valida alternativa (anche se non SQL standard). Vedi:
- Qual è il comportamento previsto per più funzioni di restituzione di set nella clausola SELECT?
Basandosi sull'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 il INNER
e OUTER
tipi di join, è necessario specificare una condizione di join, ovvero esattamente una tra NATURAL
, ON
join_condition , o USING
(join_column [, ...]). Vedi sotto per il significato.
Per CROSS JOIN
, nessuna di queste clausole può comparire.
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 (il CROSS JOIN
non richiede una condizione di unione) e is di Attila non lo era.