In Postgres 9.3 o poi utilizzare un LATERAL
registrazione:
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;
Perché LEFT JOIN LATERAL ... ON true
?
Per vecchie versioni, c'è un modo molto semplice per realizzare ciò che penso si sta cercando di con una funzione di set-ritorno (RETURNS TABLE
or RETURNS SETOF record
OR RETURNS record
):
SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM v_citizenversions v
La funzione calcola i valori o nce per ogni riga della query esterna. Se la funzione restituisce più righe, le righe risultanti vengono moltiplicate di conseguenza. Tutte le parentesi sono sintatticamente richieste per decomporre un tipo di riga. La funzione tabella potrebbe essere simile a questa:
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;
È necessario avvolgere questo in un subquery o CTE se si desidera applicare una clausola WHERE
perché le colonne non sono visibili sullo stesso livello. (Ed è meglio per le prestazioni in ogni caso, perché prevenire il ripetuto di valutazione per ogni colonna di output della funzione):
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;
Ci sono molti altri modi per fare questo o qualcosa di simile. Tutto dipende da ciò che vuoi esattamente.
Non è necessario croce si applica in Postgres. È possibile utilizzare una funzione di tabella esattamente come una funzione. Semplicemente unisciti a loro. –
@a_horse_with_no_name - 'CROSS APPLY' esegue di nuovo il TVF con parametri correlati anziché eseguirlo una volta e quindi unirsi al risultato. –