当日期相同时,从MySQL获取Next和Previous


Getting Next and Previous from MySQL When Dates Are the Same

现在我有一个问题,因为从外部源导入行到我的数据库发生得如此之快。

如果创建了多个具有完全相同发布日期的行,则不可能按日期排序并按顺序滚动帖子。

假设五行都是在11:22:04 AM生成的:

  • Row 1 - 11:22:04 AM
  • 第2行- 11:22:04 AM
  • 第3行- 11:22:04 AM
  • 第4行- 11:22:04 AM
  • 第5行- 11:22:04 AM

如果一个访问者正在查看第3行,并且想要"下一行",我将要求数据库给我发布的下一行晚于或等于11:22:04 am,无论我做什么,这将是第1行。

  • 如果我没有说"或等于",那就意味着访问者将永远无法看到第4行或第5行,这就像总是看到第1行一样糟糕。
  • 将行ID添加到order by子句并没有帮助,因为-再次-它只会总是给我第1行(如果我目前正在查看第3行)。
  • 添加大于或小于where子句没有帮助,因为-例如-如果我正在看第3行,我想要"下一个"行,但说ID需要大于3,我永远不会得到第1行。

我可以通过更新在同一时间发布的数据库中的每一行来欺骗系统,将行ID作为秒,这将把上面的记录变成:

  • Row 1 - 11:22:01 AM
  • 第2行- 11:22:02 AM
  • 第3行- 11:22:03 AM
  • 第4行- 11:22:04 AM
  • 第5行- 11:22:05 AM

这实际上很有效。问题是每次管理员导入数据时都会添加新行,而我不能不断更新数据库来纠正这个问题。

获取next和previous的查询如下:

// next row
select  t.*
from    table t
where   t.postdate  >= '{$current_date}'
and     t.postdate  < now()
and     t.id        <> {$current_id}
order   by t.postdate
limit   1
// previous row
select  t.*
from    table t
where   t.postdate  <= '{$current_date}'
and     t.postdate  < now()
and     t.id        <> {$current_id}
order   by t.postdate desc
limit   1

(是的,我在谷歌上广泛地搜索了这个问题,并在Stackoverflow上查看了几个类似的问题!)

你能试试这样吗:

// next row
select  t.*
from    table t
where   CONCAT(t.postdate, t.id)  >= '{$current_date}{$current_id}'
and     t.postdate  < now()
and     t.id        <> {$current_id}
order   by t.postdate
limit   1
// previous row
select  t.*
from    table t
where   CONCAT(t.postdate, t.id)  <= '{$current_date}{$current_id}'
and     t.postdate  < now()
and     t.id        <> {$current_id}
order   by t.postdate desc
limit   1

假设

主要假设ID字段为auto_increment。

利用它

// next row
select  t.*
from    table t
where   (( t.postdate  = '{$current_date}' AND  t.id > {$current_id})
OR t.postdate  > '{$current_date}')
and     t.postdate  < now()
order   by t.postdate, t.id
limit   1
// previous row
select  t.*
from    table t
where   (( t.postdate  = '{$current_date}' AND  t.id < {$current_id})
OR t.postdate  < '{$current_date}')
and     t.postdate  < now()
order   by t.postdate desc, t.id DESC
limit   1

就是这么简单。

也许可以稍微调整一下语法来得到你想要的结果(按asc或desc,>或<排序),但它永远不会选择同一行。>

对sql有点生透,所以也要确认语法,但显式的id检查将始终确保相同的日期以进一步区分id。

将ACS或DESC添加到ORDER BY t.id中,以帮助确保所有行都是可选的,如注释

所述

sqlfiddle证明这个概念:http://sqlfiddle.com/#!9/70e01/18

我的第一个sqlfiddle,所以如果错误请原谅,但对我来说很好。