2014-09-29 75 views
1

這是plpgsql function that returns multiple columns gets called multiple times的變體。但是,我希望找到解決我特定情況的方案。多次調用數組參數的設置返回功能

我有一個函數,它用給定的參數處理一個行數組,並返回一組行+一個新列。

CREATE OR REPLACE foo(data data[], parameter int) RETURNS SETOF enhanceddata AS 
... 

該功能適用​​於測試案例只有1組數據

SELECT * FROM foo((SELECT ARRAY_AGG(data) FROM datatable GROUP BY dataid WHERE dataid = something), 1) 

,但我想,使其與多組數據的工作,而沒有經過dataid的功能。我嘗試了一些變化:

SELECT dataid, (foo(ARRAY_AGG(data)),1).* 
FROM dataset 
WHERE dataid = something -- only testing on 1 
GROUP BY dataid 

但是該函數被調用一次每列。

+0

和'enhanceddata'是複合類型,我相信?其定義對於您的問題至關重要。因爲您描述的問題僅適用於返回多個*列*(不適用於多行)的情況。 – 2014-10-22 18:20:52

回答

3

在Postgres的9.3或更高版本,最好使用(LEFTJOIN LATERAL

SELECT sub.dataid, f.* 
FROM (
    SELECT dataid, array_agg(data) AS arr 
    FROM dataset 
    WHERE dataid = something 
    GROUP BY 1 
    ) sub 
LEFT JOIN LATERAL foo(sub.arr) f ON true; 

如果函數foo()可以返回沒有行,安全形式是LEFT JOIN LATERAL作爲證明。否則,或者如果你想排除無果行從橫向連接,應使用JOIN LATERAL或其簡寫形式:因此

, foo(sub.arr) 

This is mentioned explicitly in the manual.

我已經更新了克雷格的相關答案(由丹尼爾引用):

1

的函數被調用在這種情況下,不是因爲它的輸入多次,但由於func().*是如何實現的

這在解釋: How to avoid multiple function evals with the (func()).* syntax in an SQL query?

以下變種應該沒有多個evals上工作所有受支持的PostgreSQL版本(8.4或更新版本):

WITH subq as (
    SELECT array_agg(data) as agg, 
    dataid FROM datatable 
    -- WHERE clause ? 
    GROUP BY dataid) 
SELECT foo(agg,dataid) FROM subq; 
+0

說明和鏈接已達到目標,並接受了OP。但是提供的實際代碼無法解決分解函數調用返回的複合類型的問題。 – 2014-10-22 18:57:35