【问题标题】:filling the null data by time series按时间序列填充空数据
【发布时间】:2018-07-24 02:22:31
【问题描述】:

我有一张这样的桌子

ts                    item          infoA         infoB         
2018-02-03 12:00:00   A             null          null          
2018-02-03 12:01:00   null          A1            null          
2018-02-03 12:02:00   A             null          null          
2018-02-03 12:03:00   null          null          null          
2018-02-03 12:04:00   null          A2            null           
2018-02-03 12:05:00   null          null          null         
2018-02-03 12:06:00   B             null          null         
2018-02-03 12:07:00   null          null          B1         
2018-02-03 12:08:00   null          null          null         

我只想在相关项目上用时间序列填充空数据

ts                    item          infoA         infoB         
2018-02-03 12:00:00   A             null          null          
2018-02-03 12:01:00   A             A1            null          
2018-02-03 12:02:00   A             A1            null          
2018-02-03 12:03:00   A             A1            null          
2018-02-03 12:04:00   A             A2            null           
2018-02-03 12:05:00   A             A2            null         
2018-02-03 12:06:00   B             null          null         
2018-02-03 12:07:00   B             null          B1         
2018-02-03 12:08:00   B             null          B1            

我发现了一个 AGGREGATE 函数 GapFill() 从 this 使用该功能,我可以从

select t1.ts, t1.item, t2.infoA, t3.infoB 
from 
(select ts,gapfill(item) OVER (ORDER BY ts)) t1 
LEFT JOIN (select ts,gapfill(infoA) OVER (ORDER BY ts) as infoA) on (t1.ts = t2.ts and t1.item='A') t2 
LEFT JOIN (select ts,gapfill(infoB) OVER (ORDER BY ts) as infoB) on (t1.ts = t3.ts and t1.item='B') t3

如果我有很多列,如何简化查询。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    您想要的是lag() 上的ignore nulls 选项。但是 Postgres 还不支持它(目前)。

    也许最简单的方法是关联子查询:

    select t.ts,
           coalesce(item,
                    (select t2.item
                     from t t2
                     where t2.ts < t.ts and t2.item is not null
                     order by t2.ts desc
                     fetch first 1 row only
                    )
                   ) as item,
           coalesce(itemA,
                    (select t2.itemA
                     from t t2
                     where t2.ts < t.ts and t2.itemA is not null
                     order by t2.ts desc
                     fetch first 1 row only
                    )
                   ) as itemA,
           coalesce(itemB,
                    (select t2.itemB
                     from t t2
                     where t2.ts < t.ts and t2.itemB is not null
                     order by t2.ts desc
                     fetch first 1 row only
                    )
                   ) as itemB
    from t;
    

    如果您知道这些值是单调递增或递减的,您可以使用max() 或min()。

    使用窗口函数的另一种方法使用相同的想法。通过累积计数来识别具有相同值的行组。然后将值分布在行上:

    select t.ts,
               max(item) over (partition by grp_item) as item,
               max(itemA) over (partition by grp_item) as itemA,
               max(itemB) over (partition by grp_item) as itemB
    from (select t.*,
                        count(item) over (order by ts) as grp_item,
                        count(itemA) over (order by ts) as grp_itemA,
                        count(itemB) over (order by ts) as grp_itemB
             from t
           ) t;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 2020-05-31
      • 1970-01-01
      相关资源
      最近更新 更多