2012-01-24 75 views
0

我有一个带有两列的时间戳和跨度的MYSQL表。时间戳是一个unix时间戳,而span是一个整数。从unix中选择时间范围-timestamp

我想选择时间戳在当前时间+ - 跨度一半之间的所有行。

例如,如果当前时间是23:00,那么我希望时间戳记的时间在21到01之间的所有行。问题是,所有时间戳都来自不同的日子。

为了澄清,我不关心日期仅

,我想出了一个办法做到这一点的时间,但它似乎像这样的黑客。我敢肯定,有更多MYSQL知识的人可以让我看到一个更漂亮的方法来做到这一点。

SELECT * 
    FROM table 
    WHERE (
     TIME(DATE_SUB(CURDATE() , INTERVAL(span /2) HOUR)) <= TIME(DATE_ADD(CURDATE() , INTERVAL(span /2) HOUR)) 
     AND (
      TIME(FROM_UNIXTIME(timestamp)) >= TIME(DATE_SUB(CURDATE() , INTERVAL(span /2) HOUR)) 
      AND TIME(FROM_UNIXTIME(timestamp)) <= TIME(DATE_ADD(CURDATE() , INTERVAL(span /2) HOUR)) 
      ) 
     ) 
    OR (
     TIME(DATE_SUB(CURDATE() , INTERVAL(span /2) HOUR)) >= TIME(DATE_ADD(CURDATE() , INTERVAL(span /2) HOUR)) 
     AND (
      TIME(FROM_UNIXTIME(timestamp)) >= TIME(DATE_SUB(CURDATE() , INTERVAL(span /2) HOUR)) 
      OR TIME(FROM_UNIXTIME(timestamp)) <= TIME(DATE_ADD(CURDATE() , INTERVAL(span /2) HOUR)) 
     ) 
    ) 

回答

0

没有真正找到一个漂亮的解决方案,但这是我最终做到这一点。

SELECT * 
    FROM table 
    WHERE date_add(from_unixtime(timestamp) , INTERVAL datediff(now() , from_unixtime(timestamp)) DAY) 
    BETWEEN date_sub(now() , INTERVAL (span/2) HOUR) 
    AND date_add(now() , INTERVAL (span/2) HOUR) 
    OR date_add(from_unixtime(timestamp) , INTERVAL datediff(now() , from_unixtime(timestamp)) -1 DAY) 
    BETWEEN date_sub(now() , INTERVAL (span/2) HOUR) 
    AND date_add(now() , INTERVAL (span/2) HOUR) 
0

我推荐两种选择。

  1. 基准您的“黑客”查询,看看是否比运行两个MySQL查询更快。例如:一个查询获得目标行,另一个查询获得±1/2跨度的结果。
  2. 编写一个适当的MySQL存储过程。这实际上是选项(1),但全部在数据库中完成。

基于过去的痛苦,我不建议的另一个选择是使用MySQL变量来有效地执行两个避免存储过程的选择,例如:http://dev.mysql.com/doc/refman/5.0/en/user-variables.html。这种方法在PHP/MySQL应用程序的旧版本中很常见。

根据我的经验,赔率是不错的选择(1)既快又可读。