2012-09-25 102 views
3

考慮一個tasks表與給定字段:與最接近的指定日期(前後)檢索記錄

id | release_date | task_number 
------------------------------------- 
1 | 2012-09-01 | task_number#1 
2 | 2012-09-07 | task_number#2 
3 | 2012-09-11 | task_number#3 
4 | 2012-09-05 | task_number#4 
5 | 2012-09-21 | task_number#5 
6 | 2012-09-31 | task_number#6 

我想取回最接近的記錄(之前和之後)給定的日期。

我知道這可以通過使用兩個單獨的查詢來完成。

但是有什麼辦法可以檢索single mysql query中最接近的記錄嗎?

例如,如果給定的日期是2012-09-11,輸出應該是:

id | release_date | task_number 
    ------------------------------------- 
    2 | 2012-09-07 | task_number#2 
    3 | 2012-09-11 | task_number#3 
    5 | 2012-09-21 | task_number#5 

回答

1

下應該做的伎倆,我認爲 - 它通過使用timeDiff順序爲:

select 
    id, 
    release_date, 
    task_number 
from 
    tasks 
order by 
    abs(timediff('2012-09-11',release_date)) desc 

你可以使用您輸入的值作爲您的PHP連接中的參數,如下所示:

select 
    id, 
    release_date, 
    task_number 
from 
    tasks 
order by 
    abs(timediff(:yourDate,release_date)) desc 

並將它以相同的yyyy-mm-dd格式傳遞給相當漂亮的字符串。

編輯:從下面印章有趣的評論,似乎是準確的現場 - 但下面應該做的伎倆作爲一種解決方法:

select 
    id, 
    release_date, 
    task_number 
from 
    tasks 
order by 
    abs(time_to_sec(timediff('2012-09-11',release_date))) desc 
+0

在我最初的測試中,對timediff調用的結果調用abs會導致始終返回相同的值,無論輸入如何:8385959.000000。試試吧:'SELECT abs(TIMEDIFF('2010-12-31 23:59:59.000001','2008-12-30 01:01:01.000002'));' – chops

+0

@chops是的,我確實發現 - 有趣。基於[這個問題](http://stackoverflow.com/questions/4780128/unexpected-results-for-timediff)似乎有一個簡單的解決方法,雖然:) – Fluffeh

+0

我相信我們必須使用'datediff'而不是' timediff'。我試着修改它,但仍然返回所有行,並且不是前一行和後一行 – Prabhuram

0

如果您有關於上映時間指數,你可以做這樣賺性能更好。

select 
    id, 
    release_date, 
    abs(datediff(release_date,"$the_date")) as sort_key 
from tasks 
where 
    id = (select id from tasks where release_date > "$the_date" order by created_time limit 1)  
    or 
    id = (select id from tasks where release_date < "$the_date" order by created_time desc limit 1) 
order by sort_key limit 1; 

第一個子查詢會發現第一次約會的$ the_date後的ID,而第二個會發現最後日期的ID $ the_date之前,在那之後,我們可以很容易地選擇希望的日期。