PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Was ist das erwartete Verhalten für mehrere Set-zurückgebende Funktionen in der SELECT-Klausel?

Postgres 10 oder neuer

fügt Nullwerte für kleinere Sätze hinzu. Demo mit 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

Das Handbuch für Postgres 10 :

Wenn in der Auswahlliste der Abfrage mehr als eine Set-zurückgebende Funktion vorhanden ist, ähnelt das Verhalten dem, was Sie erhalten, wenn Sie die Funktionen in ein einziges LATERAL ROWS FROM( ... ) einfügen FROM -Klausel Artikel. Für jede Zeile der zugrunde liegenden Abfrage gibt es eine Ausgabezeile, die das erste Ergebnis jeder Funktion verwendet, dann eine Ausgabezeile, die das zweite Ergebnis verwendet, und so weiter. Wenn einige der satzzurückgebenden Funktionen weniger Ausgaben als andere erzeugen, werden die fehlenden Daten durch Nullwerte ersetzt, sodass die Gesamtzahl der Zeilen, die für eine zugrunde liegende Zeile ausgegeben werden, dieselbe ist wie für die satzzurückgebende Funktion, die die meisten Ausgaben erzeugt hat. Daher laufen die satzzurückgebenden Funktionen „im Gleichschritt“, bis sie alle erschöpft sind, und dann wird die Ausführung mit der nächsten darunter liegenden Zeile fortgesetzt.

Dies beendet das traditionell seltsame Verhalten.

Postgres 9.6 oder älter

Die Anzahl der Ergebniszeilen (etwas überraschend!) ist das kleinste gemeinsame Vielfache aller Sets im gleichen SELECT aufführen. (Wirkt nur wie ein CROSS JOIN wenn es keinen gemeinsamen Teiler für alle Mengengrößen gibt!) 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

Dokumentiert im Handbuch für Postgres 9.6 das Kapitel SQL-Funktionen, die Mengen zurückgeben , zusammen mit der Empfehlung, dies zu vermeiden:

Hinweis:Das Hauptproblem bei der Verwendung von Set-Returning-Funktionen in der Auswahlliste und nicht im FROM Klausel, ist, dass es sich nicht sehr vernünftig verhält, mehr als eine eine Menge zurückgebende Funktion in dieselbe Auswahlliste zu setzen. (Was Sie tatsächlich erhalten, wenn Sie dies tun, ist eine Anzahl von Ausgabezeilen, die gleich dem kleinsten gemeinsamen Vielfachen der Anzahl von Zeilen ist, die von jeder mengenzurückgebenden Funktion erzeugt wird. ) Der LATERAL -Syntax erzeugt weniger überraschende Ergebnisse, wenn mehrere Set-zurückgebende Funktionen aufgerufen werden, und sollte normalerweise stattdessen verwendet werden.

Fettdruck von mir.

Eine einzelne Set-Returning-Funktion ist in Ordnung (aber immer noch sauberer im FROM Liste), aber mehrfach im gleichen SELECT Liste wird jetzt abgeraten. Dies war eine nützliche Funktion, bevor wir LATERAL hatten schließt sich an. Jetzt ist es nur noch historischer Ballast.

Verwandte:

  • Paralleles Unnest() und Sortierreihenfolge in PostgreSQL
  • Entschachteln Sie mehrere Arrays parallel
  • Was ist der Unterschied zwischen LATERAL JOIN und einer Unterabfrage in PostgreSQL?