当日期相同时,从MySQL获取下一个和上一个

时间:2015-08-12 04:42:31

标签: php mysql

现在我遇到了问题,因为从外部源向我的数据库导入行的速度非常快。

如果使用完全相同的发布日期创建了多个行,则无法按日期排序并按顺序滚动帖子。

假设在上午11:22:04完成了五行:

  • 第1行 - 上午11:22:04
  • 第2行 - 上午11:22:04
  • 第3行 - 上午11:22:04
  • 第4行 - 上午11:22:04
  • 第5行 - 上午11:22:04

如果访问者正在查看第3行并希望“下一行”,我将要求数据库为我提供晚于或等于上午11:22:04发布的下一行,这将是第1行无论我做什么。

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

我可以通过更新数据库中同时发布的每一行来欺骗系统,行的ID为秒,这会将上述记录转换为:

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

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

我的下一个和上一个的查询看起来像这样:

// 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上回顾了几个类似的问题!)

2 个答案:

答案 0 :(得分:3)

你可以尝试这样的事情:

// 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

答案 1 :(得分:0)

<强>假设

主要假设是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,&gt;或&lt;排序),但它永远不会选择相同的行。

使用sql生锈,所以也要确认语法,但显式id检查将始终确保如果相同的postdate进一步按id进行区分。

<强>更新

在ORDER BY t.id中添加了ACS或DESC,以帮助确保所有行都可选,如注释中所述

<强>更新

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

我的第一个尺寸,如果有错误,请原谅,但对我来说很好。