Postgresql 如何从函数的输入参数派生返回类型中的列名?
我使用Postgres 9.5构建了以下功能:Postgresql 如何从函数的输入参数派生返回类型中的列名?,postgresql,plpgsql,postgresql-9.5,Postgresql,Plpgsql,Postgresql 9.5,我使用Postgres 9.5构建了以下功能: CREATE or REPLACE FUNCTION func_getratio_laglag(_numeratorLAG text, _n1 int, _denominatorLAG text, _n2 int, _table text) RETURNS TABLE (date_t timestamp without time zone, customer_code text, index text, ratio real) AS $BO
CREATE or REPLACE FUNCTION func_getratio_laglag(_numeratorLAG text, _n1 int, _denominatorLAG text, _n2 int, _table text)
RETURNS TABLE (date_t timestamp without time zone, customer_code text, index text, ratio real) AS
$BODY$
BEGIN
RETURN QUERY EXECUTE
'SELECT
date_t,
customer_code,
index,
(LAG('||quote_ident(_numeratorLAG)||',' || quote_literal(_n1)||') OVER W / LAG('||quote_ident(_denominatorLAG)||','|| quote_literal(_n2)||') OVER W) '
|| ' FROM ' || quote_ident(_table)
|| ' WINDOW W AS (PARTITION BY customer_code ORDER BY date_t asc);';
END;
$BODY$ LANGUAGE plpgsql;
该函数所做的只是允许我从指定的表中选择两个不同的列,并根据不同的延迟窗口计算它们之间的比率。要执行上述函数,我使用以下查询:
SELECT * FROM func_getratio_laglag('order_first',1,'order_last',0,'customers_hist');
这将返回一个列标签为date\u t
、customer\u code
、index
和ratio
的表。在如何将输出比率作为一个动态列标签方面,我一直在苦苦挣扎。也就是说,我希望它取决于输入参数,例如,如果我运行上面的select查询,那么我希望列标签date\u t
,customer\u code
,index
和order\u first\u 1\u order\u last\u 0
我被卡住了,有什么建议或提示吗
如何从函数的输入参数派生返回类型中的列名
简短的回答是:不可能。SQL对列数据类型和名称非常严格。必须在通话前或最迟在通话时申报。没有例外。没有真正的动态列名 我可以想出三个折中的解决办法: 1.列别名 按原样使用函数(或者更确切地说,我建议使用下面的已审核版本),并在函数调用中添加列别名:
SELECT * FROM func_getratio_laglag('order_first',1,'order_last',0,'customers_hist')
AS f(date_t, customer_code, index, order_first_1_order_last_0)
然后,您必须为每个调用提供列定义列表:
SELECT * FROM func_getratio_laglag('order_first',1,'order_last',0,'customers_hist')
AS f(date_t timestamp, customer_code text, index text, order_first_1_order_last_0 real)
注意表名的数据类型regclass
。这是我个人(可选)的建议
SELECT * FROM func_getratio_laglag('order_first',1,'order_last',0,'customers_hist')
AS f(date_t timestamp, customer_code text, index text, order_first_1_order_last_0 real)
CREATE OR REPLACE FUNCTION func_getratio_laglag(
_numerator_lag text, _n1 int
, _denominator_lag text, _n2 int
, _table regclass)
RETURNS TABLE (date_t timestamp, customer_code text, index text, ratio real) AS
$func$
BEGIN
RETURN QUERY EXECUTE format (
'SELECT date_t, customer_code, index
, (lag(%I, %s) OVER w / lag(%I, %s) OVER w) -- data type must match
FROM %s
WINDOW w AS (PARTITION BY customer_code ORDER BY date_t)'
, _numerator_lag, _n1, _denominator_lag, _n2, _table::text
);
END
$func$ LANGUAGE plpgsql;