I Postgres 9.3 eller senere brug en LATERAL
deltage:
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;
Hvorfor LEFT JOIN LATERAL ... ON true
?
- Optegnelsen returneret fra funktionen har kolonner sammenkædet
Til ældre versioner , der er en meget enkel måde at opnå det jeg synes på du forsøger med en sæt-retur-funktion (RETURNS TABLE
eller RETURNS SETOF record
ELLER RETURNS record
):
SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM v_citizenversions v
Funktionen beregner værdier én gang for hver række i den ydre forespørgsel. Hvis funktionen returnerer flere rækker, ganges de resulterende rækker tilsvarende. Alle parenteser er syntaktisk nødvendige at dekomponere en rækketype. Tabelfunktionen kunne se sådan ud:
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;
Du skal pakke dette ind i en underforespørgsel eller CTE, hvis du vil anvende en WHERE
klausul, fordi kolonnerne ikke er synlige på samme niveau. (Og det er alligevel bedre for ydeevnen, fordi du forhindrer gentagen evaluering for hver outputkolonne i funktionen):
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;
Der er flere andre måder at gøre dette på eller noget lignende. Det hele afhænger af, hvad du præcist vil have.