如何有效选择先前的非空值? [英] How do I efficiently select the previous non-null value?
问题描述
我在Postgres中有一个表格,如下所示:
I have a table in Postgres that looks like this:
# select * from p;
id | value
----+-------
1 | 100
2 |
3 |
4 |
5 |
6 |
7 |
8 | 200
9 |
(9 rows)
我想查询一下,使其看起来像这样:
And I'd like to query to make it look like this:
# 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)
我已经可以在选择中使用子查询来执行此操作,但是在我的真实数据中,我有20k或更多的行,并且它变得非常慢.
I can already do this with a subquery in the select, but in my real data I have 20k or more rows and it gets to be quite slow.
这可以在窗口函数中执行吗?我想使用lag(),但它似乎不支持
Is this possible to do in a window function? I'd love to use lag(), but it doesn't seem to support the IGNORE NULLS option.
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)
推荐答案
我找到了此答案(对于SQL Server)在Postgres中工作.以前从未做过,我认为这项技术非常聪明.基本上,他通过在嵌套查询中使用case语句为窗口功能创建自定义分区,该语句在值不为null时使总和递增,否则将其保留.这样一来,您就可以用与前一个非空值相同的数字来描绘每个空节.这是查询:
I found this answer for SQL Server that also works in Postgres. Having never done it before, I thought the technique was quite clever. Basically, he creates a custom partition for the windowing function by using a case statement inside of a nested query that increments a sum when the value is not null and leaves it alone otherwise. This allows one to delineate every null section with the same number as the previous non-null value. Here's the query:
SELECT
id, value, value_partition, first_value(value) over (partition by value_partition order by id)
FROM (
SELECT
id,
value,
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)
这篇关于如何有效选择先前的非空值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!