2012-09-25 58 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之前,在那之后,我们可以很容易地选择希望的日期。