Trong Postgres 9.3 hoặc sau đó sử dụng LATERAL
tham gia:
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;
Tại sao LEFT JOIN LATERAL ... ON true
?
- Bản ghi được trả về từ hàm có các cột được nối với nhau
Đối với phiên bản cũ hơn , có một cách rất đơn giản để thực hiện những gì Tôi nghĩ bạn đang cố gắng thực hiện với chức năng set-return (RETURNS TABLE
hoặc bản ghi RETURNS SETOF record
HOẶC RETURNS record
):
SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM v_citizenversions v
Hàm tính toán các giá trị một lần cho mỗi hàng của truy vấn bên ngoài. Nếu hàm trả về nhiều hàng, các hàng kết quả sẽ được nhân lên tương ứng. Tất cả dấu ngoặc đơn là bắt buộc về mặt cú pháp để phân hủy một loại hàng. Hàm bảng có thể trông giống như sau:
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;
Bạn cần bao bọc điều này trong một truy vấn con hoặc CTE nếu bạn muốn áp dụng WHERE
mệnh đề vì các cột không hiển thị trên cùng một mức. (Và nó vẫn tốt hơn cho hiệu suất, vì bạn ngăn chặn đánh giá lặp lại cho mọi cột đầu ra của hàm):
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;
Có một số cách khác để làm điều này hoặc điều gì đó tương tự. Tất cả phụ thuộc vào chính xác những gì bạn muốn.