加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读