2012-06-24 75 views
2

爲了對web服務器上的傳入數據做一些統計,我對這些數據做了一些ETL工作。所以我總結了一些基於四分之一小時的事情。即:計算時間(到下一個時間段的整數時間)

inserted | tstamp 
8:00  8:00 
8:09  8:00 
8:16  8:15 
8:29  8:15 
8:42  8:30 
8:45  8:45 
8:59  8:45 
9:01  9:00 

以上的列是datetime列,其中還包含一個日期(我離開它僅用於演示目的)。該作業每3分鐘通過cron運行一次,並且只接收最近3分鐘的數據。現在,當cron作業在工作時崩潰時,存在風險,即當下一次作業重新啓動時,時隙包含錯誤的數據。所以我希望這份工作能夠在最後一個時間段開始。即當作業在上次08:24運行並崩潰時,應該在08:15再次啓動。

我的問題是現在,是否有一個簡單的MySQL語句,它給了我實際時間之前的最後一個時間段?

我使用ETL來確定實際的時隙中的語句是

CONCAT(
    DATE_FORMAT(a.inserted, '%Y-%m-%d %H:'), 
    IF(MINUTE(a.inserted)<15,'00', 
     IF(MINUTE(a.inserted)<30,'15', 
     IF(MINUTE(a.inserted)<45,'30', 
     '45')) 
    ), 
    ':00' 
) AS tstamp 

難道這更優雅的方式做?

+0

您的查詢隱含你的'real_time'列不是日期。是嗎? – Ben

+0

對不起,這只是時間片的一個例子。當然,這是一個包含日期的'datetime'列。 – rabudde

回答

2

您可以使用unix_timestamp()獲得以秒爲單位的當前時間自1970年最後3分鐘的間隔是一次模3 * 60秒:

select from_unixtime(unix_timestamp() - mod(unix_timestamp(), 180)) 
      as StartOfInterval 
,  from_unixtime(unix_timestamp() - mod(unix_timestamp(), 180)-180) 
      as StartOfLastInterval 

Live example at SQL Fiddle.

+0

我的意思是間隔15分鐘;)但我更喜歡你的解決方案,因爲我在PHP中做了更多的時間計算。所以我在PHP中使用時間函數,並在我的SQL查詢中包含計算的戳記 – rabudde

1

你很關。這個怎麼樣?

SELECT DATE_FORMAT(a.inserted '%Y-%m-%d %H:00:00') + 
    INTERVAL (MINUTE(a.inserted) - MINUTE(a.inserted)%15) MINUTE 
+0

真的很棒的方法(我希望我可以接受;)但是因爲我在PHP中做了更多的時間計算我使用@Andomars提示 – rabudde

1

只需使用FLOOR()向下舍分鐘的15倍數:

CONCAT(DATE_FORMAT(a.inserted, '%Y-%m-%d %H:'), 
    15 * FLOOR(MINUTE(a.inserted)/15)), ':00') AS tstamp 

或時間使用FLOOR()和格式化:

DATE_FORMAT(FROM_UNIXTIME(900 * FLOOR(UNIX_TIMESTAMP(a.inserted)/900)), '%Y-%m-%d %H:%M:%s') as tstamp 

900是秒數在15分鐘內)