用postgres中的中位数填充缺失值

Filling in missing values with a median in postgres

如何用中位数计算替换 avg?

select *
, coalesce(val, avg(val) over (order by t rows between 3 preceding and 1 preceding)) as fixed
from (
    values
    (1, 10),
    (2, NULL),
    (3, 10),
    (4, 15),
    (5, 11),
    (6, NULL),
    (7, NULL),
    (8, NULL),
    (9, NULL)
) as test(t, val)
;

这个有正版吗?

percentile_cont(0.5) within group(order by val) over (order by t rows between 3 preceding and 1 preceding)

不幸的是 percentile_cont() 是一个聚合函数,没有等效的 window 函数。

一种解决方法是使用内联子查询进行聚合计算。

如果ids一直在增加,那么你可以这样做:

select 
    t.*,
    coalesce(
        t.val, 
        (
            select percentile_cont(0.5) within group(order by t1.val)
            from test t1
            where t1.id between t.id - 3 and t.id - 1
        )
    ) fixed
from test t

否则,您需要额外的嵌套级别:

select 
    t.*,
    coalesce(
        t.val, 
        (
            select percentile_cont(0.5) within group(order by t1.val)
            from (select val from test t1 where t1.id < t.id order by t1.id desc limit 3) t1
        )
    ) fixed
from test t

Demo on DB Fiddle - 两个查询都产生:

id |  val | fixed
-: | ---: | :----
 1 |   10 | 10   
 2 | null | 10   
 3 |   10 | 10   
 4 |   15 | 15   
 5 |   11 | 11   
 6 | null | 11   
 7 | null | 13   
 8 | null | 11   
 9 | null | null