多次调用数组参数的设置返回功能

问题描述:

这是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

在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.

我已经更新了克雷格的相关答案(由丹尼尔引用):

的函数被调用在这种情况下,不是因为它的输入多次,但由于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