sql - 将记录分组到不连续的一小时存储箱中

标签 sql ms-access ms-access-2007

我有以下形式的事件数据,其中 eventId 为 long,时间为日期/时间(为简单起见,下面仅显示时间,因为所有时间都在同一天):

eventId    time
---------------
   1       0712
   2       0715
   3       0801
   4       0817
   5       0916
   6       1214
   7       2255

我需要形成包含一个小时的事件的组,其中该小时是从该组中的第一次开始测量的。使用上述数据我的分组将是

Group 1 (0712 to 0811 inclusive): events 1, 2, 3
Group 2 (0817 to 0916 inclusive): events 4, 5
Group 3 (1214 to 1313 inclusive): event 6
Group 4 (2255 to 2354 inclusive): event 7

我发现了很多按预定义时间段(例如每小时、每天、5 分钟)对数据进行分组的示例,但没有像我想要做的那样。我怀疑直接使用 SQL 是不可能的...这似乎是一个先有鸡还是先有蛋的问题,我需要根据数据本身将数据放入容器中。

这个问题的基石是提出每个范围的开始时间,但除了这个简单的情况之外我无法想出任何东西:第一个开始时间。

我能想到的唯一方法是以编程方式(在 VBA 中)执行此操作,其中我将数据选择到临时表中,并在将行放入垃圾箱时删除它们。换句话说,找到最早的时间,然后抓取该时间以及该时间之后 1 小时内的所有记录,将它们从表中删除。获取剩余记录的最早时间并重复,直到临时表为空。

理想情况下,我想要一个 SQL 解决方案,但我无法自己想出任何接近的解决方案。

最佳答案

关于可能方法的一些说明。

Dim rs As DAO.Recordset
Dim db As Database
Dim rsBins As DAO.Recordset
Dim qdf As QueryDef 'Demo

Set db = CurrentDb

'For demonstration, if the code is to be run frequently
'just empty the bins table
db.Execute "DROP TABLE Bins"
db.Execute "CREATE TABLE Bins (ID Counter, Bin1 Datetime, Bin2 Datetime)"

'Get min start times
db.Execute "INSERT INTO bins ( Bin1, Bin2 ) " _
   & "SELECT Min([time]) AS Bin1, DateAdd('n',59,Min([time])) AS Bin2 " _
   & "FROM events"

Set rsBins = db.OpenRecordset("Bins")

Do While True
    Set rs = db.OpenRecordset("SELECT Min([time]) AS Bin1, " _
    & "DateAdd('n',59,Min([time])) AS Bin2 FROM events " _
    & "WHERE [time] > (SELECT Max(Bin2) FROM Bins)")

    If IsNull(rs!Bin1) Then
        Exit Do
    Else
        rsBins.AddNew
        rsBins!Bin1 = rs!Bin1
        rsBins!bin2 = rs!bin2
        rsBins.Update
    End If
Loop

''Demonstration of final query.
''This will only run once and then error becaue the query exists, but that is
''all you need after that, just open the now existing binned query

sSQL = "SELECT events.Time, bins.ID, bins.Bin1, bins.Bin2 " _
     & "FROM events, bins " _
     & "GROUP BY events.Time, bins.ID, bins.Bin1, bins.Bin2 " _
     & "HAVING (((events.Time) Between [bin1] And [bin2]));"

Set qdf = db.CreateQueryDef("Binned", sSQL)
DoCmd.OpenQuery qdf.Name

关于sql - 将记录分组到不连续的一小时存储箱中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13904588/

相关文章:

sql - 仅当传递的参数具有值时才使用 Where 子句中的 'Exists'

ms-access - ms access - 基于文本框值的复选框

vba - 在 MS Access 中使用 Application.FileDialog(msoFileDialogSaveAs) 时预设 "save as type"字段

database - 如何将 MS Access 数据库 (.mdb) 文件转换为 Sqlite?

c# - 我的应用程序和 Access 查询向导之间的不同 LIKE 行为

sql - 运行插入 SQL 查询

ms-access - 带有 VBA 的 MS Access 链接表

mysql - 将值拆分为其他几列

php - 3合1 mysql语句

SQLite:多个聚合列