使用 Postgres 继承缺失值的长序列

Ran*_*ize 5 postgresql null count window-functions gaps-and-islands

我有一张这样的表:

create table foo (foo_label text, foo_price int, foo_date date);

insert into foo (
          values
          ('aaa', 100,  '2017-01-01'),
          ('aaa', NULL, '2017-02-01'),
          ('aaa', NULL, '2017-03-01'),
          ('aaa', NULL, '2017-04-01'),
          ('aaa', 140,  '2017-05-01'),
          ('aaa', NULL, '2017-06-01'),
          ('aaa', 180,  '2017-07-01')
        );
Run Code Online (Sandbox Code Playgroud)

如您所见,foo_price列上的一些值丢失了。

我需要的是缺失值以这种方式用“前一个”可用值填充:

 foo_label | fixed_foo_price | foo_date
-----------+-----------------+------------
 aaa       | 100             | 2017-01-01
 aaa       | 100             | 2017-02-01
 aaa       | 100             | 2017-03-01
 aaa       | 100             | 2017-04-01
 aaa       | 140             | 2017-05-01
 aaa       | 140             | 2017-06-01
 aaa       | 180             | 2017-07-01
Run Code Online (Sandbox Code Playgroud)

我的尝试:

select 
    foo_label, 
    (case when foo_price is null then previous_foo_price else foo_price end) as fixed_foo_price,
    foo_date
from (
  select 
      foo_label, 
      lag(foo_price) OVER (PARTITION BY foo_label order by foo_date::date) as previous_foo_price, 
      foo_price,
      foo_date
      from foo
) T;
Run Code Online (Sandbox Code Playgroud)

正如您从这里看到的:

https://www.db-fiddle.com/#&togetherjs=s6giIonUxT

它并没有完全填满“100”系列。

知道我怎样才能得到想要的结果吗?

Erw*_*ter 10

我会用窗口函数形成组,count()然后为每个组取第一个值:

SELECT foo_label
     , first_value(foo_price) OVER (PARTITION BY foo_label, grp ORDER BY foo_date) AS fixed_foo_price
     , foo_date
FROM  (
   SELECT foo_label
        , count(foo_price) OVER (PARTITION BY foo_label ORDER BY foo_date) AS grp
        , foo_price
        , foo_date
   FROM   foo
   ) sub;
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为count()只计算非空值。因此,所有具有 NULL 的行都与具有实际值的最后一行在同一组中。正是您所需要的。