【问题标题】:Return zero for time slot if data is not present如果数据不存在,则时隙返回零
【发布时间】:2017-02-08 15:09:42
【问题描述】:

我正在尝试每分钟获取两分钟的数据,对于 mid、sid、pid 组合,每秒应该有数据。如果每个组合的数据在一秒钟内不存在,则应将 IC 值返回为零。两分钟内,如果任何时隙的 mid、sid、pid 组合不存在数据,则将有 120 个时隙,则应返回零。这data 用于绘制折线图,​​如果数据不存在,则应归零。

CREATE TABLE [dbo].[DeviceData](
[Id] [BIGINT] IDENTITY(1,1) NOT NULL,
[MId] [INT] NOT NULL,
[SId] [INT] NOT NULL,
[PId] [INT] NOT NULL,
[DataTime] [DATETIME] NOT NULL,
[IC] [INT] NOT NULL,
CONSTRAINT [PK_DeviceData] PRIMARY KEY CLUSTERED 
(
[Id] ASC
)

 SELECT  [MId] ,
    [SId] ,
    [PId] ,
    [DataTime] ,
    SUM([IC]) AS Value
 FROM    [DeviceData]
 WHERE   DataTime BETWEEN DATEADD(MINUTE, -2, GETUTCDATE())
             AND     GETUTCDATE()
 GROUP BY [MId] ,
    SID ,
    PId ,
    [DataTime];

【问题讨论】:

  • 创建一个存储值 0 - 120 的帮助表。外连接。
  • 这比听起来要复杂。当你有小数秒的数据时会发生什么?还是 xx:xx:00:00 和 xx:xx:00.999 处的数据?
  • 这是实时数据,如果每次创建表都要重新创建,时隙会有所不同,所以担心性能,不需要考虑秒的分数。

标签: sql sql-server sql-server-2008


【解决方案1】:

你需要一个数字 CTE:

with Numbers as
(
select 1 as NN
union all
select NN+1
from Numbers
where NN < 120
)
, Times as
(
select dateadd(ss, 
               NN, 
               DATEADD(MINUTE, 
                       -2, 
                       dateadd(ms, 
                               -datepart(ms, 
                                        GETUTCDATE()),
                               GETUTCDATE()) ) as Timeslot
from Numbers
)
select Timeslot, DD.*
from Times
left join DeviceData DD
  on Timeslot = dateadd(ms, -datepart(ms, GETUTCDATE()),GETUTCDATE())
OPTION (MAXRECURSION 1000) -- This will bypass the recursion error

【讨论】:

  • 感谢您的回复。我收到此错误“语句已终止。在语句完成之前,最大递归 100 已用尽。”
  • @shijithmc maxrecursion 默认为 100,使用上述选项克服此问题
  • 感谢它已解决,但这不会返回 mid、sid 或 pid
猜你喜欢
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 2018-04-10
  • 1970-01-01
相关资源
最近更新 更多