2012-01-24 95 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)既快又可讀。