前言
在做文章列表时遇见一个问题,文章列表的排序由三个字段决定:isTop、id、sort。
而在文章详情页面我需要根据当前文章的id,来拿到当前文章的上下文,这就导致普通的只根据id排序的那种方法不再适用。
先看一下单字段排序的方法:
-- 上一篇
SELECT id, title FROM `article` WHERE id < 14 ORDER BY id DESC LIMIT 1
-- 下一篇
SELECT id, title FROM `article` WHERE id > 14 ORDER BY id ASC LIMIT 1
但是对于多字段,这种方法就不太适用了,where条件也没法控制。
原理
既然单字段比较好实现,那就试着吧所有排序字段整理成一个字段,然后继续用上面的那种方法来实现。
mysql是根据字符串排序的,所以要保证整合好的字段长度统一,根据字段优先级进行合并即可。
例子
假设排序字段isTop为int类型,值取0或者1。
sort为int类型,最大四位,可以为null。
id为int类型,最大9位。
假设相对文章id为10,则可以如下面的方法实现:
-- 普通分页,通过page和pagesize控制分页
SELECT `id`, `title`
from article
ORDER BY isTop DESC, sort DESC, id DESC
LIMIT 0,5
-- 合并字段分页,通过page和pagesize控制分页
SELECT `id`, `title`, CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) as a1
from article
ORDER BY a1 DESC
LIMIT 0,5
-- 上一篇
SELECT `id`, `title`, CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) as a1
from article
WHERE CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) > (
select CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) from article where id=10
)
ORDER BY a1 ASC
LIMIT 0,1
-- 下一篇
SELECT `id`, `title`, CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) as a1
from article
WHERE CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) < (
select CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) from article where id=10
)
ORDER BY a1 DESC
LIMIT 0,1
-- 根据最后一条数据id取下一页
SELECT `id`, `title`, CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) as a1
from article
WHERE CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) < (
select CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) from article where id=10
)
ORDER BY a1 DESC
LIMIT 0,3
-- 根据最前一条数据id取上一页,(需程序再反转一下)
SELECT `id`, `title`, CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) as a1
from article
WHERE CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) > (
select CONCAT_WS('-', isTop,LPAD(IFNULL(sort, ''), 4, '0'),LPAD(id, 9, '0')) from article where id=10
)
ORDER BY a1 ASC
LIMIT 0,3
这是我目前实现的方法,如果您有更好的方法,欢迎在下方评论,非常感谢!
路人
1/25/2023, 5:07:49 PM
何必
8/26/2024, 4:31:21 PM