2013-05-17 68 views
4

是否有計算給定運行時間戳彼此接近,但不一定在固定時間範圍內?MySQL計數具有相似時間戳的行

即,不按小時或分鐘進行分組,而是按當前行的時間戳接近下一行的時間戳的程度進行分組。如果下一行在「x」秒/分鐘內,那麼將該行添加到組中,否則開始新的分組。

鑑於這樣的數據:

+----+---------+---------------------+ 
| id | item_id | event_date   | 
+----+---------+---------------------+ 
| 1 |  1 | 2013-05-17 11:59:59 | 
| 2 |  1 | 2013-05-17 12:00:00 | 
| 3 |  1 | 2013-05-17 12:00:02 | 
| 4 |  1 | 2013-05-17 12:00:03 | 
| 5 |  3 | 2013-05-17 14:05:00 | 
| 6 |  3 | 2013-05-17 14:05:01 | 
| 7 |  3 | 2013-05-17 15:30:00 | 
| 8 |  3 | 2013-05-17 15:30:01 | 
| 9 |  3 | 2013-05-17 15:30:02 | 
| 10 |  1 | 2013-05-18 09:12:00 | 
| 11 |  1 | 2013-05-18 09:13:30 | 
| 12 |  1 | 2013-05-18 09:13:45 | 
| 13 |  1 | 2013-05-18 09:14:00 | 
| 14 |  2 | 2013-05-20 15:45:00 | 
| 15 |  2 | 2013-05-20 15:45:03 | 
| 16 |  2 | 2013-05-20 15:45:10 | 
| 17 |  2 | 2013-05-23 07:36:00 | 
| 18 |  2 | 2013-05-23 07:36:10 | 
| 19 |  2 | 2013-05-23 07:36:12 | 
| 20 |  2 | 2013-05-23 07:36:15 | 
| 21 |  1 | 2013-05-24 11:55:00 | 
| 22 |  1 | 2013-05-24 11:55:02 | 
+----+---------+---------------------+ 

期望的結果:

+---------+-------+---------------------+ 
| item_id | total | last_date_in_group | 
+---------+-------+---------------------+ 
|  1 |  4 | 2013-05-17 12:00:03 | 
|  3 |  2 | 2013-05-17 14:05:01 | 
|  3 |  3 | 2013-05-17 15:30:02 | 
|  1 |  4 | 2013-05-18 09:14:00 | 
|  2 |  3 | 2013-05-20 15:45:10 | 
|  2 |  4 | 2013-05-23 07:36:15 | 
|  1 |  2 | 2013-05-24 11:55:02 | 
+---------+-------+---------------------+ 

回答

1

這是有點複雜。首先,您需要的是每個記錄的下一個事件的時間。以下子查詢以這樣的時間(nexted)增加了,如果是界限內:

select t.*, 
     (select event_date 
      from t t2 
      where t2.item_id = t.item_id and 
       t2.event_date > t.event_date and 
       <date comparison here> 
      order by event_date limit 1 
     ) as nexted 
    from t 

這使用相關子查詢。 <date comparison here>適用於任何需要比較的日期。當沒有記錄時,該值將爲NULL。

現在,有了這個信息(nexted)有一個技巧來獲得分組。對於任何記錄,這是nexted爲空後的第一個事件時間。這將是系列賽中的最後一場比賽。不幸的是,這需要兩層嵌套的相關子查詢(或與聚合的連接)。結果看起來有點笨拙:

select item_id, GROUPING, MIN(event_date) as start_date, MAX(event_date) as end_date, 
     COUNT(*) as num_dates 
from (select t.*, 
      (select min(t2.event_date) 
       from (select t1.*, 
          (select event_date 
          from t t2 
          where t2.item_id = t1.item_id and 
            t2.event_date > t1.event_date and 
            <date comparison here> 
          order by event_date limit 1 
          ) as nexted 
        from t1 
        ) t2 
       where t2.nexted is null 
      ) as grouping 
     from t 
    ) s 
group by item_id, grouping; 
+0

這看起來很有前途,感謝您的幫助!我只有一個關於的問題。我假設如果我想要最大1分鐘的差距,它會看起來像(UNIX_TIMESTAMP(t2.event_date)-UNIX_TIMESTAMP(t1.event_date))<3600? – tburnside

+0

@ tburnside。 。 。是的,我認爲這對MySQL是正確的。說實話,MySQL中的日期/時間函數總是讓我感到困惑,所以我發現自己重新回到了文檔中。 –

0

大約從發現每一個人記錄的地方協會接近它,然後從每個記錄的發現的最大事件日期分組什麼。這是基於一個靜態差的時間間隔(在我的例子5分鐘)

SELECT item_id, MAX(total), MAX(last_date_in_group) AS last_date_in_group FROM (
    SELECT t1.item_id, COUNT(*) AS total, COALESCE(GREATEST(t1.event_date, MAX(t2.event_date)), t1.event_date) AS last_date_in_group 
     FROM table_name t1 
     LEFT JOIN table_name t2 ON t2.event_date BETWEEN t1.event_date AND t1.event_date + INTERVAL 5 MINUTE 
     GROUP BY t1.id 
    ) t 
    GROUP BY last_date_in_group 
+0

時間戳的運行可能會或可能不會在同一分鐘。他們可能不到一分鐘,但在不同的分鐘。 '2013-05-17 12:00:45和2013-05-17 12:01:15' 這些不到一分鐘,但會在不同的分組。例如,同樣的事情會在最後和一小時的開始時間用於時間戳。 – tburnside

+0

我已更新我的查詢,您對此有何看法?除了靜態的時間框架外,我會從任何事件日期的開始給出5分鐘窗口的「屏障」,您可以根據需要在左連接的條件下進行調整。我會補充一點,我的方法確實有可能在多個時間段內存在條目,具體取決於您如何寬恕您的5分鐘屏障 – Bryan

相關問題