从unix-timestamp中选择时间范围

时间:2012-01-24 23:10:10

标签: mysql date timestamp range timespan

我有一个MYSQL表,有两列,时间戳和跨度。 timestamp是一个unix-timestamp,而span是一个整数。

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

EG。如果当前时间是23:00,那么我想要时间戳时间在21到01之间的所有行。问题当然是所有时间戳都来自不同的日期。

TO CLARIFY,我不关心日期只有时间

我已经找到了一种方法来做到这一点,但它看起来像是一个黑客。我确信拥有更多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 ) )
        )
    )

2 个答案:

答案 0 :(得分:0)

我推荐两种选择。

  1. 对您的“黑客”查询进行基准测试,看看这是否比运行两个MySQL查询更快。例如:一个查询来获取目标行,另一个查询获得结果为±1/2跨度。
  2. 编写正确的MySQL存储过程。这实际上是选项(1),但都是在DB内部完成的。
  3. 根据过去的痛苦,我不推荐的另一个选择是使用MySQL变量来有效地做两个选择来避免存储过程,例如:http://dev.mysql.com/doc/refman/5.0/en/user-variables.html。这种方法在PHP / MySQL应用程序的旧时代很常见。

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

答案 1 :(得分: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 )