postgresql – 如何有效地选择以前的非空值?
发布时间:2020-12-13 16:38:39 所属栏目:百科 来源:网络整理
导读:我在Postgres中有一张表,看起来像这样: # select * from p; id | value ----+------- 1 | 100 2 | 3 | 4 | 5 | 6 | 7 | 8 | 200 9 | (9 rows) 我想查询,使其看起来像这样: # select * from p; id | value | new_value----+-------+---------- 1 | 100 |
我在Postgres中有一张表,看起来像这样:
# select * from p; id | value ----+------- 1 | 100 2 | 3 | 4 | 5 | 6 | 7 | 8 | 200 9 | (9 rows) 我想查询,使其看起来像这样: # select * from p; id | value | new_value ----+-------+---------- 1 | 100 | 2 | | 100 3 | | 100 4 | | 100 5 | | 100 6 | | 100 7 | | 100 8 | 200 | 100 9 | | 200 (9 rows) 我可以用select中的子查询来做这个,但是在我的实际数据中,我有20k行或更多的行,它的速度很慢。 这是否可以在窗口函数中执行?我很乐意使用lag(),但似乎并不支持IGNORE NULLS选项。 select id,value,lag(value,1) over (order by id) as new_value from p; id | value | new_value ----+-------+----------- 1 | 100 | 2 | | 100 3 | | 4 | | 5 | | 6 | | 7 | | 8 | 200 | 9 | | 200 (9 rows)
我发现也可以在Postgres中使用SQL Server的
this answer。从来没有这样做,我以为这个技巧很聪明。基本上,他通过使用嵌套查询内的case语句为窗口函数创建一个自定义分区,当该值不为空时,它将增加一个总和,否则单独留下。这样就可以使用与前一个非空值相同的数字来描绘每个空白部分。这是查询:
SELECT id,value_partition,first_value(value) over (partition by value_partition order by id) FROM ( SELECT id,sum(case when value is null then 0 else 1 end) over (order by id) as value_partition FROM p ORDER BY id ASC ) as q 结果: id | value | value_partition | first_value ----+-------+-----------------+------------- 1 | 100 | 1 | 100 2 | | 1 | 100 3 | | 1 | 100 4 | | 1 | 100 5 | | 1 | 100 6 | | 1 | 100 7 | | 1 | 100 8 | 200 | 2 | 200 9 | | 2 | 200 (9 rows) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |