在多列中向前填充NULL值

时间:2019-09-25 23:43:21

标签: sql postgresql timescaledb

我有一个表,其中包含一些时间序列数据。

             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

我该如何实现?

我正在使用带有timescaledb扩展名的postgresql 10

2 个答案:

答案 0 :(得分:2)

您可以通过几个窗口函数来完成此操作。在子查询中,我们将使用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 :(得分:1)

将此简单方便的汇总函数用于填补空白的一般目的:

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.