Postgres 10 eller senare
lägger till nollvärden för mindre uppsättning(ar). Demo med 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 här
Manualen för Postgres 10 :
Om det finns mer än en set-returnerande funktion i frågans urvalslista, liknar beteendet det du får av att placera funktionerna i en enda
LATERAL ROWS FROM( ... )
FROM
-klausulpost. För varje rad från den underliggande frågan finns en utdatarad som använder det första resultatet från varje funktion, sedan en utdatarad som använder det andra resultatet och så vidare. Om några av de set-returerande funktionerna ger färre utgångar än andra, ersätts null-värden för den saknade data, så att det totala antalet rader som emitteras för en underliggande rad blir detsamma som för den set-returnerande funktion som producerade flest utdata. Således körs de set-returnerande funktionerna "i låst steg" tills alla är slut, och sedan fortsätter exekveringen med nästa underliggande rad.
Detta avslutar det traditionellt udda beteendet.
Postgres 9.6 eller äldre
Antalet resultatrader (något överraskande!) är den lägsta gemensamma multipeln av alla uppsättningar i samma SELECT
lista. (Finger bara som en CROSS JOIN
om det inte finns någon gemensam divisor för alla uppsättningsstorlekar!) 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 här
Dokumenterat i manualen för Postgres 9.6 kapitlet SQL-funktioner som returnerar uppsättningar , tillsammans med rekommendationen att undvika det:
Obs:Huvudproblemet med att använda set-retur-funktioner i urvalslistan, snarare än
FROM
klausul, är att det inte beter sig särskilt förnuftigt att lägga in fler än en återvändande funktion i samma vallista. (Vad du faktiskt får om du gör det är ett antal utmatningsrader lika med den minsta gemensamma multipeln av antalet rader som produceras av varje setreturerande funktion. )LATERAL
syntax ger fria överraskande resultat när man anropar flera setreturnerande funktioner, och bör vanligtvis användas istället.
Djärv betoning min.
En funktion för att återställa en enda set är OK (men fortfarande renare i FROM
). lista), men flera i samma SELECT
listan är avskräckt nu. Detta var en användbar funktion innan vi hade LATERAL
ansluter sig. Nu är det bara historisk barlast.
Relaterat:
- Parallell unnest() och sorteringsordning i PostgreSQL
- Ta bort flera arrayer parallellt
- Vad är skillnaden mellan LATERAL JOIN och en underfråga i PostgreSQL?