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 的行都与具有实际值的最后一行在同一组中。正是您所需要的。