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

Postgres analog zu CROSS APPLY in SQL Server

In Postgres 9.3 oder verwenden Sie später ein LATERAL beitreten:

SELECT v.col_a, v.col_b, f.*  -- no parentheses here, f is a table alias
FROM   v_citizenversions v
LEFT   JOIN LATERAL f_citizen_rec_modified(v.col1, v.col2) f ON true
WHERE  f.col_c = _col_c;

Warum LEFT JOIN LATERAL ... ON true ?

  • Von der Funktion zurückgegebener Datensatz hat verkettete Spalten

Für ältere Versionen , gibt es einen sehr einfachen Weg, um zu erreichen, was ich denke Sie versuchen es mit einer Set-Returning-Funktion (RETURNS TABLE oder RETURNS SETOF record ODER RETURNS record ):

SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM   v_citizenversions v

Die Funktion berechnet Werte einmal für jede Zeile der äußeren Abfrage. Wenn die Funktion mehrere Zeilen zurückgibt, werden die resultierenden Zeilen entsprechend multipliziert. Alle Klammern sind syntaktisch erforderlich um einen Zeilentyp zu zerlegen. Die Tabellenfunktion könnte etwa so aussehen:

CREATE OR REPLACE FUNCTION f_citizen_rec_modified(_col1 int, _col2 text)
  RETURNS TABLE(col_c integer, col_d text) AS
$func$
SELECT s.col_c, s.col_d
FROM   some_tbl s
WHERE  s.col_a = $1
AND    s.col_b = $2
$func$ LANGUAGE sql;

Sie müssen dies in eine Unterabfrage oder CTE einschließen, wenn Sie ein WHERE anwenden möchten -Klausel, da die Spalten nicht auf derselben Ebene sichtbar sind. (Und es ist sowieso besser für die Leistung, weil Sie eine wiederholte Auswertung für jede Ausgabespalte der Funktion verhindern):

SELECT col_a, col_b, (f_row).*
FROM (
   SELECT col_a, col_b, f_citizen_rec_modified(col1, col2) AS f_row
   FROM   v_citizenversions v
   ) x
WHERE (f_row).col_c = _col_c;

Es gibt mehrere andere Möglichkeiten, dies oder ähnliches zu tun. Es hängt alles davon ab, was Sie genau wollen.