【问题标题】:Retrieving records with the closest (before and after) given date检索给定日期最近(之前和之后)的记录
【发布时间】:2012-09-25 09:24:34
【问题描述】:

考虑一个带有给定字段的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

【问题讨论】:

    标签: php mysql


    【解决方案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
    

    【讨论】:

    • 在我的初始测试中,对 timediff 调用的结果调用 abs 会导致无论输入如何,总是返回相同的值:8385959.000000。试试看:SELECT abs(TIMEDIFF('2010-12-31 23:59:59.000001','2008-12-30 01:01:01.000002'));
    • @chops 是的,我确实觉得这很有趣。基于this question,似乎有一个简单的解决方法:)
    • 我相信我们必须使用datediff 而不是timediff。我也尝试修改它,但它仍然返回所有行,而不是完全返回前一行和后一行
    • @BPRAM dateDiff 只会返回天数的差异,所以我使用 timediff 来提供更准确的order by 但是,如果您的数据仅基于日期,它可能会很有吸引力:)
    • @Fluffeh 是的,我明白你的意思。问题是它没有给我想要的输出。所以我决定使用UNION ALL 函数来组合两个不同条件的记录。
    【解决方案2】:

    如果你在 release_date 有索引,你可以这样做以获得更好的性能。

    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,第二个子查询会找到$the_date之前的最后一个日期的id,之后我们就可以轻松选择想要的日期了。

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多