Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何从函数的输入参数派生返回类型中的列名?_Postgresql_Plpgsql_Postgresql 9.5 - Fatal编程技术网

Postgresql 如何从函数的输入参数派生返回类型中的列名?

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

我使用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
$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
。这是我个人(可选)的建议

旁白:我还建议不要在Postgres中使用混合的大小写标识符


您的文字上写着Postgres 9.5,我冒昧地对标签进行了相应的调整。谢谢您的帮助,谢谢您提供的详细信息。只是重申一下,对于我所寻求的问题没有解决方案,您建议的解决方法(特别是第1点)只是重命名列,如果我决定更改任何输入,仍然需要手动完成重命名。可能需要寻找另一种解决方案,比如将其输入python数据帧。@RRoszko:是的。但仔细想想:无论如何,您都是在提供列名作为函数参数。是什么阻止您也提供派生列别名?我最初设想使用循环,以便将参数输入到滞后计算中,例如0、1、2等。老实说,我目前没有深入考虑它,它更像是一种特殊计算。
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;