如何将Postgres函数的结果保存到变量中?

时间:2019-06-13 05:53:17

标签: sql postgresql plpgsql sql-function

我有一个Postgres函数,该函数应该返回一列。

CREATE FUNCTION  fillvals_v1 (source_column numeric , order_by_col numeric) RETURNS numeric AS $$
    DECLARE
      fv_value numeric;
    BEGIN
        BEGIN
              select
                  first_value(src_col) over (partition by partition_col) as corrected_col
                      from (
                          select source_column as src_col, order_by_col,
                              sum(case when source_column is not null then 1 end) over (order by order_by_col) as partition_col
                                  from table_name
              ) t into fv_value;
              return cast(fv_value as numeric);
        END;
    END;
$$ LANGUAGE plpgsql STABLE;

表table_name具有这样的值

seq | close
-------+-------
     1 |     3
     2 |     4
     3 |     5
     4 |
     5 |
     6 |     3
(6 rows)

所以当我这样调用此函数

select fillvals_v1(close, seq) from table_name;

它给了我下面的结果

fillvals_v1
-------------
           3
           4
           5


           3
(6 rows)

这是不正确的。

我想要的实际结果是

   seq | close
-------+-------
     1 |     3
     2 |     4
     3 |     5
     4 |     5
     5 |     5
     6 |     3
(6 rows)

也就是说,我希望所有空白都填充为非NULL的最新值(按seq排序)。

有人可以告诉我这里出了什么问题吗?也许我的函数中缺少某些东西,或者将函数结果保存到变量中的方式可能不正确。

1 个答案:

答案 0 :(得分:1)

您想要的是IGNORE NULLS上的LAG()选项。 las,Postgres还不支持该功能。

我建议:

select t.*, max(close) over (partition by grp)       
from (select t.*,
             count(close) over (order by seq) as grp
      from tablename t
     ) t;

您还可以使用横向联接(或子查询):

select t.seq,
       coalesce(t.close, tprev.close) as close
from tablename t left join lateral
     (select tprev.*
      from t tprev
      where tprev.seq < t.seq and
            t.close is null and
            tprev.close is not null
      order by tprev.seq desc
     ) tprev;

第一种方法应该更快。