【问题标题】:SQL - Time serie - Return 0 for missing valuesSQL - 时间序列 - 缺失值返回 0
【发布时间】:2017-08-21 23:44:47
【问题描述】:

我有一个名为 MY_TABLE(例如)的 MS/Azure SQL 表,其中包含两列:

  • datetime : INT = UNIX epoch(测量的日期和时间)
  • val : DECIMAL(测量值)

此表代表一个时间序列,通常以 1 分钟为单位。数据中可能存在一些差距/缺失值。 SQL 数据库链接到 Django Web 应用程序,其中时间序列将显示在图表上。

我使用以下查询以 1 小时的分辨率检索两个日期之间的聚合数据:

    WITH time_table as (
        SELECT cast(dateadd(second, datetime, '19700101') as DATETIME) as calendar_date,val,datetime as epoch
        FROM MY_TABLE
        WHERE datetime>=1451628000 and datetime<1452755200
    )
    SELECT min(epoch),avg(val) 
    FROM time_table
    GROUP BY YEAR(calendar_date),MONTH(calendar_date),DAY(calendar_date),datepart(hour,calendar_date)
    ORDER BY min(calendar_date) ASC

此查询返回 1 小时内聚合的平均值。

问题

  1. 即使表中没有对应的数据,我如何才能在所有时间步中将此查询修改为值 (0)。更清楚地说,我希望结果是一个连续的时间序列,没有任何时间间隔

我可以使用 Python/Pandas 轻松执行此操作,但我觉得不会优化

【问题讨论】:

  • 我将创建一个包含时间列表的临时表,并将其与您在问题中的查询连接。
  • 目前尚不完全清楚问题是什么,但我认为您希望在不存在行时返回一行。为此,您需要一个包含您想要返回的每个值的表。将其设为查询的主表,然后对您的值进行左连接。
  • 感谢您的快速答复!我对 SQL 不是很熟悉:如何为两个日期之间的每个时间生成一个零值表?

标签: sql sql-server azure time-series


【解决方案1】:

您可以使用 Epoch 表单和 datetime 表单生成小时表:

create table dbo.Hours (
   EpochStart bigint not null primary key clustered
 , EpochEnd   bigint not null
 , Datetime_Hour datetime not null
 , Datetime_NextHour datetime not null
);

declare @fromdate datetime = '20160101';
declare @thrudate datetime = '20161231';

;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, Hours as (
  select top ((datediff(day, @fromdate,@thrudate)+1)*24)
      [Datetime_Hour]=convert(datetime,dateadd(hour,row_number() over(order by (select 1))-1,@fromdate))
     ,[Datetime_NextHour]=convert(datetime,dateadd(hour,row_number() over(order by (select 1)),@fromdate))
  from n as deka cross join n as hecto cross join n as kilo 
                cross join n as tenK cross join n as hundredK
   order by 1
)
insert into dbo.Hours
select
   EpochStart = datediff(second,'19700101',Datetime_Hour)
 , EpochEnd   = datediff(second,'19700101',Datetime_NextHour)
 , Datetime_Hour
 , Datetime_NextHour
from Hours;

然后像这样在查询中使用它:

select 
   h.EpochStart
 , avg(val)
from dbo.Hours h
  left join MY_TABLE t
    on t.datetime >= h.EpochStart
   and t.datetime <  h.EpochEnd
where h.EpochStart >= 1451628000
  and h.EpochStart <  1452755200
group by h.EpochStart

rextester 演示:http://rextester.com/INZW16141

【讨论】:

  • @totor 乐于助人!
猜你喜欢
  • 2016-03-28
  • 2021-01-22
  • 2022-01-15
  • 2016-11-21
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 2018-05-14
  • 2014-04-29
相关资源
最近更新 更多