使用 MySQL 进行有序分页
Posted
技术标签:
【中文标题】使用 MySQL 进行有序分页【英文标题】:Ordered pagination with MySQL 【发布时间】:2017-10-13 11:22:38 【问题描述】:更新: 在下面的问题中,我认为当你选择行时,mysql 会创建一种行索引,然后 LIMIT 和 OFFSET 子句通过它的数字切断这个列表。问题是我使用错误的值或字段组合对行进行排序,因为它们具有几乎相同的值。
这是我的错误,假设 MySQL 有很多“智能”;-)
解决办法总是有一个更可靠的排序字段作为后备,比如ID,就像这样ORDER BY priority DESC, id ASC
这是一个严格的 MySQL 问题。为什么似乎在 ORDER BY 之前应用了 LIMIT OFFSET 子句?或者我错过了什么?
这里是示例,首先我们选择一个按优先级字段排序的行列表:
SELECT d0_.name, d0_.id AS id_0, d0_.priority AS priority_1 FROM destination d0_ WHERE d0_.active = 1 ORDER BY d0_.priority DESC;
结果如下所示:
然后我想使用以下查询从该列表中选择前 10 行:
SELECT d0_.name, d0_.id AS id_0, d0_.priority AS priority_1 FROM destination d0_ WHERE d0_.active = 1 ORDER BY d0_.priority DESC LIMIT 10 OFFSET 10;
我得到了这个结果:
为什么列表没有从“Grandvalira”到“Sierra nevada”?
这个问题,不是实际的顺序,而是有些行永远无法到达!比如“Vallnord Ordino-Arcalís”。当我更改 OFFSET 值时,它不会遍历所有行,并且它会重复一些行。
这是基本问题。但这在使用 Symfony 的“KnpPaginatorBundle (2.5.3)”时给我带来了问题。我以为是 php 代码的问题,但是 mysql 查询给了我这个意想不到的结果。
有什么帮助或线索吗?
谢谢!
【问题讨论】:
您的问题太混乱了 IMO,我无法给出答案,但我不明白“Grandvalira”到“Sierra nevada”范围的意义是什么?在完整的按字母顺序排序的列表中,这两个位置都不是第一个或最后一个。尽量简化你的问题,直奔主题。 【参考方案1】:您没有得到预期的结果,因为您的数据中有许多行具有相同的优先级值。
当您对优先级使用“排序依据”时,所有具有优先级的行可以按任意顺序排列。不能保证具有相同优先级值的排序。要解决平局,您可以在 order by 子句中添加其他字段。根据您的选择,您可以选择在“order by”子句中包含名称或 ID 字段。
【讨论】:
你说得对,我刚刚遇到这个问题。我需要添加一个更可靠的排序字段。例如,如果我使用 id,它就可以工作。以上是关于使用 MySQL 进行有序分页的主要内容,如果未能解决你的问题,请参考以下文章