Postgres 10 of nieuwer
voegt null-waarden toe voor kleinere set(s). Demo met 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 hier
De handleiding voor Postgres 10 :
Als er meer dan één set-retourfunctie in de selectielijst van de query is, is het gedrag vergelijkbaar met wat u krijgt als u de functies in een enkele
LATERAL ROWS FROM( ... )
plaatstFROM
-clausule artikel. Voor een rij van de onderliggende query is er een uitvoerrij die het eerste resultaat van elke functie gebruikt, vervolgens een uitvoerrij die het tweede resultaat gebruikt, enzovoort. Als sommige van de set-retournerende functies minder uitvoer produceren dan andere, worden de ontbrekende gegevens vervangen door null-waarden, zodat het totale aantal rijen dat wordt uitgezonden voor één onderliggende rij hetzelfde is als voor de set-retourfunctie die de meeste outputs produceerde. Dus de set-retourfuncties worden "in lockstep" uitgevoerd totdat ze allemaal zijn uitgeput, en dan gaat de uitvoering verder met de volgende onderliggende rij.
Dit maakt een einde aan het traditioneel vreemde gedrag.
Postgres 9.6 of ouder
Het aantal resultaatrijen (enigszins verrassend!) is het kleinste gemene veelvoud van alle sets in dezelfde SELECT
lijst. (Werkt alleen als een CROSS JOIN
als er geen gemeenschappelijke deler is voor alle set-sizes!) 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 hier
Gedocumenteerd in handleiding voor Postgres 9.6 het hoofdstuk SQL-functies die sets retourneren , samen met de aanbeveling om het te vermijden:
Opmerking:het belangrijkste probleem met het gebruik van set-returning-functies in de selectielijst, in plaats van de
FROM
clausule, is dat het niet erg verstandig is om meer dan oneset-retournerende functies in dezelfde select-lijst te plaatsen. (Wat u feitelijk krijgt als u dit doet, is een aantal uitvoerrijen dat gelijk is aan het kleinste gemene veelvoud van het aantal rijen dat door elke set-retournerende functie wordt geproduceerd. ) DeLATERAL
syntaxis levert minder verrassende resultaten op bij het aanroepen van meerdere set-return-functies, en zou in plaats daarvan moeten worden gebruikt.
Vetgedrukte nadruk van mij.
Een enkele set-retourfunctie is OK (maar nog steeds schoner in de FROM
lijst), maar meerdere in dezelfde SELECT
lijst is nu ontmoedigd. Dit was een handige functie voordat we LATERAL
. hadden doet mee. Nu is het slechts historische ballast.
Gerelateerd:
- Parallel unnest() en sorteervolgorde in PostgreSQL
- Meerdere arrays parallel verwijderen
- Wat is het verschil tussen LATERAL JOIN en een subquery in PostgreSQL?