2012-06-24 76 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分钟内)