В Postgres 9.3 или по-късно използвайте LATERAL
присъединете се:
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;
Защо LEFT JOIN LATERAL ... ON true
?
- Записът, върнат от функцията, има конкатенирани колони
За по-стари версии , има много прост начин да постигнете това, което мисля опитвате се с функция за връщане на набор (RETURNS TABLE
или RETURNS SETOF record
ИЛИ RETURNS record
):
SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM v_citizenversions v
Функцията изчислява стойности веднъж за всеки ред от външната заявка. Ако функцията върне няколко реда, получените редове се умножават съответно. Всички скоби са синтактично задължителни за разлагане на тип ред. Функцията на таблицата може да изглежда така:
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;
Трябва да обвиете това в подзаявка или CTE, ако искате да приложите WHERE
клауза, защото колоните не се виждат на едно и също ниво. (И така или иначе е по-добре за производителност, защото предотвратявате многократно оценяване за всяка изходна колона на функцията):
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;
Има няколко други начина да направите това или нещо подобно. Всичко зависи от това какво точно искате.