2012-12-16 38 views
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 ......它似乎是一個雞與雞蛋問題,我需要根據數據本身將數據放入容器中。

這個問題的基石是每個範圍的開始時間,但我不能拿出任何超越平凡的情況:第一個開始時間。

我可以想出的唯一方法是以編程方式(在VBA中)執行此操作,其中將數據選擇到臨時表中並在將它們放入容器時刪除行。換句話說,找到最早的時間,然後在1小時內抓取該記錄和所有記錄,將其從表格中刪除。獲取剩餘記錄的最早時間並重復,直到臨時表爲空。

理想情況下,我想要一個SQL解決方案,但我無法拿出任何接近我自己的東西。

+0

既然每個垃圾箱的開始和垃圾箱的數量都不是固定的,我認爲你堅持使用程序化解決方案。遞歸SQL可能會提供一個解決方案,但AFAIK Jet SQL不支持公用表表達式,也不支持它們遞歸:-(所以我認爲你是正確的,一個VBA解決方案是要走的。 –

+0

對不起,我編輯了我的答案爲了清晰起見,理想情況下,我想要一個SQL解決方案,時間是日期/時間;我上面的表示只是一個簡化 – Paul

回答

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 
+0

你是一個天才......這真是太棒了!只是碰巧你的其他答案之一解決了另一個問題我曾經......感謝兩次救我! – Paul

+0

我的榮幸:) – Fionnuala