Заполнение пропущенных значений медианой в postgres - PullRequest
1 голос
/ 13 февраля 2020

Как я могу заменить среднее значение в этом вычислении на среднее значение?

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)

1 Ответ

0 голосов
/ 13 февраля 2020

К сожалению percentile_cont() - это агрегатная функция, для которой нет эквивалентной оконной функции.

Один из обходных путей - использовать встроенный подзапрос для выполнения агрегатного вычисления.

Если id s всегда увеличивается, тогда вы можете сделать:

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

Демонстрация на DB Fiddle - оба запроса дают:

id |  val | fixed
-: | ---: | :----
 1 |   10 | 10   
 2 | <em>null</em> | 10   
 3 |   10 | 10   
 4 |   15 | 15   
 5 |   11 | 11   
 6 | <em>null</em> | 11   
 7 | <em>null</em> | 13   
 8 | <em>null</em> | 11   
 9 | <em>null</em> | <em>null</em> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...