我有一张这样的桌子:
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')
);
如您所见,该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
我的尝试:
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;
从这里可以看出:
https://www.db-fiddle.com/#&togetherjs=s6giIonUxT
它并没有完全填满“100”系列。
知道如何获得想要的结果吗?
我将使用窗口函数组成组,
count()
然后为每个组取第一个值:这是有效的,因为
count()
只计算非空值。因此,所有行NULL
最终与具有实际值的最后一行位于同一组中。正是你需要的。前导 NULL 值(实际上是“0”组)以
NULL
.COALESCE
如果需要,请添加默认值。例如填写0
而不是NULL
:在 postgresql 演练演示中回填缺失的数据
创建一个
my_money
用索引、带空值的数字和一个日期调用的表,然后插入一些行。制作一个临时表来构造我们的回填列,命名为:
backfilled_cci_val
到目前为止一切都很好,但我们不能回填第一个空值,因为它没有先验,所以你必须通过更新手动决定默认的开始值:
最后一步是将新表中的 backfilled_cci_val 替换回原始表中的 cci_val:
或者,如果您喜欢危险地生活并一次性就地回填:
此更新语句与上述所有语句相同,只是它位于现有表上。
这会产生与上述相同的最终结果。