PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Qual è il comportamento previsto per più funzioni di restituzione di set nella clausola SELECT?

Postgres 10 o più recente

aggiunge valori nulli per insiemi più piccoli. Demo con generate_series() :

SELECT generate_series( 1,  2) AS row2
     , generate_series(11, 13) AS row3
     , generate_series(21, 24) AS row4;
row2 | row3 | row4
-----+------+-----
   1 |   11 |   21
   2 |   12 |   22
null |   13 |   23
null | null |   24

dbfiddle qui

Il manuale per Postgres 10 :

Se è presente più di una funzione di restituzione di set nell'elenco di selezione della query, il comportamento è simile a quello che si ottiene inserendo le funzioni in un singolo LATERAL ROWS FROM( ... ) FROM -elemento della clausola. Per ogni riga della query sottostante è presente una riga di output che utilizza il primo risultato di ciascuna funzione, quindi una riga di output che utilizza il secondo risultato e così via. Se alcune delle funzioni di restituzione degli insiemi producono meno output di altre, i valori nulli vengono sostituiti per i dati mancanti, in modo che il numero totale di righe emesse per una riga sottostante sia lo stesso della funzione di restituzione degli insiemi che ha prodotto la maggior parte degli output. Pertanto le funzioni di restituzione del set vengono eseguite "in lockstep" fino a quando non sono tutte esaurite, quindi l'esecuzione continua con la riga sottostante successiva.

Questo pone fine al comportamento tradizionalmente strano.

Postgres 9.6 o precedente

Il numero di righe dei risultati (sorprendentemente!) è il multiplo comune più basso di tutti i set nello stesso SELECT elenco. (Funziona solo come un CROSS JOIN se non esiste un divisore comune per tutte le dimensioni dei set!) Demo:

SELECT generate_series( 1,  2) AS row2
     , generate_series(11, 13) AS row3
     , generate_series(21, 24) AS row4;
row2 | row3 | row4
-----+------+-----
   1 |   11 |   21
   2 |   12 |   22
   1 |   13 |   23
   2 |   11 |   24
   1 |   12 |   21
   2 |   13 |   22
   1 |   11 |   23
   2 |   12 |   24
   1 |   13 |   21
   2 |   11 |   22
   1 |   12 |   23
   2 |   13 |   24

dbfiddle qui

Documentato nel manuale di Postgres 9.6 il capitolo Funzioni SQL che restituiscono insiemi , insieme alla raccomandazione di evitarlo:

Nota:il problema principale con l'utilizzo delle funzioni di restituzione dei set nell'elenco di selezione, anziché nel FROM clausola, è che inserire più di una funzione di restituzione di un insieme nella stessa lista di selezione non si comporta in modo molto sensato. (Quello che ottieni effettivamente se lo fai è un numero di righe di output uguale al minimo comune multiplo del numero di righe prodotte da ciascuna funzione di restituzione dell'insieme. ) Il LATERAL la sintassi non produce risultati sorprendenti quando si chiamano più funzioni di restituzione di set, e di solito dovrebbe essere usata al suo posto.

Enfasi in grassetto la mia.

Una singola funzione di restituzione del set è OK (ma è ancora più pulita nel FROM list), ma multipli nello stesso SELECT elenco è sconsigliato ora. Questa era una funzione utile prima che avessimo LATERAL si unisce. Ora è solo una zavorra storica.

Correlati:

  • Unnest() parallelo e ordinamento in PostgreSQL
  • Disnida più array in parallelo
  • Qual ​​è la differenza tra LATERAL JOIN e una sottoquery in PostgreSQL?