# 使用窗口函数在分区中结转第一个非空值

12

``````create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)``````

``````ts| person    |  somevalue
-------------------------
1 |  bob      |null
2 |  bob      |null
3 |  jim      |null
4 |  bob      |  A
5 |  bob      | null
6 |  bob      |  B
7 |  jim      |  X
8 |  jim      |  Y
9 |  jim      |  null``````

``````ts|  person   | somevalue | carry-forward
-----------------------------------------------
1 |  bob      |null       |   null
2 |  bob      |null       |   null
3 |  jim      |null       |   null
4 |  bob      |  A        |    A
5 |  bob      | null      |    A
6 |  bob      |  B        |    B
7 |  jim      |  X        |    X
8 |  jim      |  Y        |    Y
9 |  jim      |  null     |    Y``````

`````` select *,
first_value(somevalue) over (partition by person order by (somevalue is null), ts rows between UNBOUNDED PRECEDING AND current row  ) as carry_forward

from visits
order by ts``````

1
@a_horse_with_no_name应该是一个答案。
ypercubeᵀᴹ

12

``````select *, first_value(somevalue) over w as carryforward_somevalue
from (
select *, sum(case when somevalue is null then 0 else 1 end) over (partition by person order by id ) as value_partition
from test1

) as q
window w as (partition by person, value_partition order by id);``````

5

ypercubeᵀᴹ

5

``````with recursive
cf as
(
( select distinct on (person)
v.*, v.somevalue as carry_forward
from visits as v
order by person, ts
)
union all
select
v.*, coalesce(v.somevalue, cf.carry_forward)
from cf
join lateral
( select v.*
from visits as v
where v.person = cf.person
and v.ts > cf.ts
order by ts
limit 1
) as v
on true
)
select cf.*
from cf
order by ts ;``````

maxTrialfire，2016年

1

ypercubeᵀᴹ