考虑一个类似于以下数据的表
column_a (boolean) | column_order (integer)
TRUE | 1
NULL | 2
NULL | 3
TRUE | 4
NULL | 5
FALSE | 6
NULL | 7
Run Code Online (Sandbox Code Playgroud)
我想编写一个查询,根据指定的顺序将每个NULL
值替换为列的先前值中的column_a
最后一个非NULL
值column_order
.结果应如下所示:
column_a (boolean) | column_order (integer)
TRUE | 1
TRUE | 2
TRUE | 3
TRUE | 4
TRUE | 5
FALSE | 6
FALSE | 7
Run Code Online (Sandbox Code Playgroud)
为简单起见,我们可以假设第一个值永远不为空.如果连续NULL
值不超过一个,则以下情况有效:
SELECT
COALESCE(column_a, lag(column_a) OVER (ORDER BY column_order))
FROM test_table
ORDER BY column_order;
Run Code Online (Sandbox Code Playgroud)
但是,上述内容对于任意数量的连续NULL
值都不起作用.什么是能够实现上述结果的Postgres查询?是否存在可以很好地扩展到大量行的高效查询?
您可以使用一个方便的技巧,根据空序列和非空序列之间的划分来创建分区,然后sum
将它们向前推进。case
first_value
例如
select
*,
sum(case when column_a is not null then 1 else 0 end)
OVER (order by column_order) as partition
from table1;
column_a | column_order | partition
----------+--------------+-----------
t | 1 | 1
| 2 | 1
| 3 | 1
t | 4 | 2
| 5 | 2
f | 6 | 3
| 7 | 3
(7 rows)
Run Code Online (Sandbox Code Playgroud)
然后
select
first_value(column_a)
OVER (PARTITION BY partition ORDER BY column_order),
column_order
from (
select
*,
sum(case when column_a is not null then 1 else 0 end)
OVER (order by column_order) as partition
from table1
) partitioned;
Run Code Online (Sandbox Code Playgroud)
给你:
first_value | column_order
-------------+--------------
t | 1
t | 2
t | 3
t | 4
t | 5
f | 6
f | 7
(7 rows)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1813 次 |
最近记录: |