简体   繁体   中英

Retrieving records with the closest (before and after) given date

Consider a tasks table with the given fields :

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

I would like to retrieve records closest(before and after) to a given date.

I know this can be done by using two separate queries.

But is there any way to retrieve the closest record in a single mysql query ?

For example if the given date is 2012-09-11 , the output should be :

    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

The following should do the trick I think - it uses timeDiff in the order by:

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

You could use the value you are entering as a parameter in your connection from PHP like this:

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

And pass it the string in the same yyyy-mm-dd format quite nicely.

Edit: Interesting comment from chops below, seems spot on accurate - however the following should do the trick as a workaround:

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

If you have index on release_date, you can do it like this to earn a better performance.

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 first subquery will find the id of first date after $the_date, and the second one will find the id of last date before $the_date, after that, we can choose the desire date easily.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM