sql >> Databasteknik >  >> RDS >> PostgreSQL

Vad är det förväntade beteendet för flera set-returnerande funktioner i SELECT-satsen?

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?


  1. Hur ska jag skicka ett tabellnamn till en lagrad proc?

  2. Hur fyller man i ListView med db i tillgångsmappen?

  3. PL/SQL-samling:Kapslad tabell i Oracle-databas

  4. if (välj antal (kolumn) från tabellen)> 0 då