3

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

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 是不可能的……这似乎是一个先有鸡还是先有蛋的问题,我需要根据数据本身将数据放入 bin 中。

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

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

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

4

1 回答 1

2

关于可能的方法的一些注释。

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
于 2012-12-16T20:31:55.250 回答