将缺少的时间段添加到select查询(sql server)

将缺少的时间段添加到select查询(sql server),sql,sql-server,vba,Sql,Sql Server,Vba,我正在使用底部的代码从sql server中提取所述日期的时间戳和其他一些数据,以便制作一个图表,这很简单 该查询将时间值组合为5分钟范围,因此,例如,所有条目12:00-12:05将成为一个结果,并显示该时间范围内适用列的最大值 我遇到的问题是,如果缺少数据,我希望查询返回缺少的5分钟范围的空行,基本上没有这些间隙,我需要在excel中运行大量数组公式,这需要几分钟而不是一秒钟 因此,总的例子是: DateTime Parts_Made Alarm_Light 2020-06-01 1

我正在使用底部的代码从sql server中提取所述日期的时间戳和其他一些数据,以便制作一个图表,这很简单

该查询将时间值组合为5分钟范围,因此,例如,所有条目12:00-12:05将成为一个结果,并显示该时间范围内适用列的最大值

我遇到的问题是,如果缺少数据,我希望查询返回缺少的5分钟范围的空行,基本上没有这些间隙,我需要在excel中运行大量数组公式,这需要几分钟而不是一秒钟

因此,总的例子是:

DateTime    Parts_Made  Alarm_Light
2020-06-01 12:03    5   0
2020-06-01 12:07    6   0
2020-06-01 12:23    8   0


Would return

DateTime    Parts_Made  Alarm_Light
2020-06-01 12:05    5   0
2020-06-01 12:10    6   0      
2020-06-01 12:15    6   0    <-- inserted "missing" row could also be 12:10 - 0 -0 or 12:10  null null I can work around whatever we can come up with
2020-06-01 12:20    6   0    <-- "another" missing row
2020-06-01 12:25    8   0
我最初的想法是在一天内创建一个表,每一个可能的5分钟的时间范围,并加入到结果中,创建空白的行,在那里没有数据,但是我无法弄清楚如何在VBA/Excel中工作。 查询代码:

 selectCmd.ActiveConnection = adoDbConn
   selectCmd.CommandText = "SELECT DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101') as Date_Time " & _
    " ,max(Part_Count)-min(Part_Count) as PartsMade" & _
    ", max(Alarm_Light) as Alarmlight" & _
    ", max(PV_Alarm) as Alarm" & _
    " FROM [SMP].[dbo].[33_TestImport] " & _
    " Where [DateTime]>= DateAdd(Hour, DateDiff(Hour, 0, '" & DateYMD & "')-0, 0) AND [DateTime]<= DateAdd(Hour, DateDiff(Hour, 0, '" & DateYMD & "')+24, 0) " & _
    " AND Machine_Number = " & Machvar & " " & _
    " Group BY DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101') "

您可以使用递归CTE构建时间框架,然后通过以下方式左键联接和分组:


如果预期的次数超过100次,则添加选项maxrecursion 0。

嘿,谢谢你的回答,我一直在想这个问题。我正在使用UNION、INTERSECT或EXCEPT运算符组合所有查询,它们的目标列表中的表达式数必须相等。在第一次查询中,时间与最初的时间相同,但与此处列出的日期/时间有问题。因为我真的不明白前几行是怎么回事,你能提供多一点指导吗?
with times as (
      select convert(datetime, 2020-06-01 12:05) as dt, 1 as lev
      union all
      select dateadd(minute, 5, dt), lev + 1
      from times
      where lev < 5
     )
select dt.dt,
       max(t.Part_Count)-min(Part_Count) as PartsMade,
       max(t.Alarm_Light) as Alarmlight,
       max(t.PV_Alarm) as Alarm
from times t left join
     [SMP].[dbo].[33_TestImport] ti
     on ti.datetime >= t.dt and
        ti.datetime < dateadd(minute, 5, t.dt) and
        ti.machine = ?
group by t.dt
order by t.dt;