Как заполнить Null предыдущим значением в PostgreSQL? - PullRequest
0 голосов
/ 18 марта 2019

У меня есть таблица, которая содержит нулевые значения.Мне нужно заменить их предыдущим ненулевым значением.Это пример данных, которые у меня есть:

   date    | category | start_period | period_number |
------------------------------------------------------
2018-01-01 |    A     |       1      |       1       |
2018-01-02 |    A     |       0      |      Null     |
2018-01-03 |    A     |       0      |      Null     |
2018-01-04 |    A     |       0      |      Null     |
2018-01-05 |    B     |       1      |       2       |
2018-01-06 |    B     |       0      |      Null     |
2018-01-07 |    B     |       0      |      Null     |
2018-01-08 |    A     |       1      |       3       |
2018-01-09 |    A     |       0      |      Null     |
2018-01-10 |    A     |       0      |      Null     |

Результат должен выглядеть следующим образом:

   date    | category | start_period | period_number |
------------------------------------------------------
2018-01-01 |    A     |       1      |       1       |
2018-01-02 |    A     |       0      |       1       |
2018-01-03 |    A     |       0      |       1       |
2018-01-04 |    A     |       0      |       1       |
2018-01-05 |    B     |       1      |       2       |
2018-01-06 |    B     |       0      |       2       |
2018-01-07 |    B     |       0      |       2       |
2018-01-08 |    A     |       1      |       3       |
2018-01-09 |    A     |       0      |       3       |
2018-01-10 |    A     |       0      |       3       |

Я пробовал следующий запрос, но в этом случае только первый Nullзначение будет заменено.

select 
date,
category,
start_period,
case
    when period_number isnull then lag(period_number) over()
    else period_number
end as period_number
from period_table;

Кроме того, я пытался использовать first_value() оконную функцию, но я не знаю, как установить правильное окно.

Любая помощь очень ценится.

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Вы можете объединить таблицу с собой и получить желаемое значение.Предполагая, что ваш столбец даты является первичным ключом или уникальным.

update your_table upd set period_number = tbl.period_number 
from
(
   select b.date, max(b2.date) as d2 from your_table b 
   inner join d_batch_tab b2 on b2.date< b.date and b2.period_number  is not null 
   group by b.date
)t 
inner join your_table tbl on tbl.date = t.d2
where t.date= upd.date

Если вам не нужно обновлять таблицу, а только оператор выбора, то

select yt.date, yt.category, yt.start_period, tbl.period_number
from your_table yt
inner join 
(
   select b.date, max(b2.date) as d2 from your_table b 
   inner join d_batch_tab b2 on b2.date< b.date and b2.period_number  is not null 
   group by b.date
)t on yt.date = t.date
inner join your_table tbl on tbl.date = t.d2
0 голосов
/ 18 марта 2019

Если вы замените выписку по делу на:

(
    select
        _.period_number
    from
        period_table as _
    where
        _.period_number is not null
        and _.category = period_table.category
        and _.date <= period_table.date
    order by
        _.date desc
    limit 1
) as period_number

Тогда это должно иметь ожидаемый эффект. Это далеко не так элегантно, как оконная функция, но я не думаю, что оконные функции достаточно гибки для вашего конкретного случая использования (или, по крайней мере, если они есть, я не знаю, как их так сильно сгибать)

...