Вперед заполнить значения NULL в нескольких столбцах - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть таблица, которая содержит некоторые данные временных рядов.

             time              |  bid   |  ask   
-------------------------------+--------+--------
 2018-12-27 01:04:06.978456+00 | 1.7086 |       
 2018-12-27 01:04:07.006461+00 | 1.7087 |       
 2018-12-27 01:04:07.021961+00 |        | 1.7106
 2018-12-27 01:04:08.882591+00 | 1.7025 | 1.7156
 2018-12-27 01:04:09.374118+00 |        | 1.7106
 2018-12-27 01:04:09.39018+00  | 1.7087 | 1.7156      
 2018-12-27 01:04:15.793528+00 | 1.7045 | 
 2018-12-27 01:04:15.833545+00 | 1.7083 |       
 2018-12-27 01:04:15.893536+00 |        | 1.7096
 2018-12-27 01:04:16.258062+00 | 1.7045 | 1.7095
 2018-12-27 01:04:16.653573+00 | 1.7046 | 1.7148
 2018-12-27 01:04:16.665564+00 |        | 1.7097

Я хотел бы заполнить значения NULL, чтобы результат моего запроса выглядел так:

             time              |  bid   |  ask   
-------------------------------+--------+--------
 2018-12-27 01:04:06.978456+00 | 1.7086 |       
 2018-12-27 01:04:07.006461+00 | 1.7087 |       
 2018-12-27 01:04:07.021961+00 | 1.7087 | 1.7106
 2018-12-27 01:04:08.882591+00 | 1.7025 | 1.7156
 2018-12-27 01:04:09.374118+00 | 1.7025 | 1.7106
 2018-12-27 01:04:09.39018+00  | 1.7087 | 1.7156      
 2018-12-27 01:04:15.793528+00 | 1.7045 | 1.7156
 2018-12-27 01:04:15.833545+00 | 1.7083 | 1.7156      
 2018-12-27 01:04:15.893536+00 | 1.7083 | 1.7096
 2018-12-27 01:04:16.258062+00 | 1.7045 | 1.7095
 2018-12-27 01:04:16.653573+00 | 1.7046 | 1.7148
 2018-12-27 01:04:16.665564+00 | 1.7046 | 1.7097

Как мне этого добиться?

Я использую postgresql 10 с расширением timescaledb

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Вы можете сделать это с помощью пары оконных функций.В подзапросе мы будем использовать count для подсчета строк, исключая нули, до текущей строки, упорядоченной по времени, что позволит нам выяснить отдельные группы.Оттуда мы можем просто использовать first_value этой группы, если она еще не имеет значения.

select t,
       coalesce(bid, first_value(bid) OVER (partition by bid_group ORDER BY t)) as bid_filled,
       coalesce(ask, first_value(ask) OVER (partition by ask_group ORDER BY t)) as ask_filled
FROM (
  select t, ask, bid,
         count(bid) OVER (order by t) as bid_group,
         count(ask) OVER (order by t) as ask_group
  FROM test
) sub;
             t              | bid_filled | ask_filled
----------------------------+------------+------------
 2018-12-27 01:04:06.978456 |     1.7086 |
 2018-12-27 01:04:07.006461 |     1.7087 |
 2018-12-27 01:04:07.021961 |     1.7087 |     1.7106
 2018-12-27 01:04:08.882591 |     1.7025 |     1.7156
 2018-12-27 01:04:09.374118 |     1.7025 |     1.7106
 2018-12-27 01:04:09.39018  |     1.7087 |     1.7156
 2018-12-27 01:04:15.793528 |     1.7045 |     1.7156
 2018-12-27 01:04:15.833545 |     1.7083 |     1.7156
 2018-12-27 01:04:15.893536 |     1.7083 |     1.7096
 2018-12-27 01:04:16.258062 |     1.7045 |     1.7095
 2018-12-27 01:04:16.653573 |     1.7046 |     1.7148
 2018-12-27 01:04:16.665564 |     1.7046 |     1.7097
1 голос
/ 26 сентября 2019

Используйте эту простую и удобную функцию агрегирования для общего заполнения пробелов:

create or replace function last_func(anyelement, anyelement)
returns anyelement language sql immutable strict
as $$
    select $2;
$$;

create aggregate last(anyelement) (
    sfunc = last_func,
    stype = anyelement
);

Запрос:

select time, last(bid) over w as bid, last(ask) over w as ask
from my_table
window w as (order by time)
order by time

            time            |  bid   |  ask   
----------------------------+--------+--------
 2018-12-27 01:04:06.978456 | 1.7086 |       
 2018-12-27 01:04:07.006461 | 1.7087 |       
 2018-12-27 01:04:07.021961 | 1.7087 | 1.7106
 2018-12-27 01:04:08.882591 | 1.7025 | 1.7156
 2018-12-27 01:04:09.374118 | 1.7025 | 1.7106
 2018-12-27 01:04:09.39018  | 1.7087 | 1.7156
 2018-12-27 01:04:15.793528 | 1.7045 | 1.7156
 2018-12-27 01:04:15.833545 | 1.7083 | 1.7156
 2018-12-27 01:04:15.893536 | 1.7083 | 1.7096
 2018-12-27 01:04:16.258062 | 1.7045 | 1.7095
 2018-12-27 01:04:16.653573 | 1.7046 | 1.7148
 2018-12-27 01:04:16.665564 | 1.7046 | 1.7097
(12 rows)

Db <> Fiddle.

...