1. MySql实现分组排序
1.1表说明
小说章节表
CREATE TABLE fiction_chapter ( id int(11) NOT NULL, chapter_id varchar(32) NOT NULL COMMENT ‘章节id’, fiction_id varchar(32) NOT NULL COMMENT ‘小说id’, chapter_sub_sort int(11) DEFAULT NULL COMMENT ‘卷序号’, chapter_sub_name varchar(255) DEFAULT NULL COMMENT ‘卷’, chapter_sort int(12) DEFAULT NULL COMMENT ‘章节号’, chapter_name varchar(255) DEFAULT NULL COMMENT ‘章节名称’, create_time datetime NOT NULL COMMENT ‘创建时间’, update_time datetime NOT NULL COMMENT ‘更新时间’, PRIMARY KEY (chapter_id ), KEY fiction_id (fiction_id ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1.2 数据样例
1.3 需求与实现
需要查询出每本小说的最新章节 sql:
SELECT t.* FROM ( SELECT * , IF(@bak=fiction_id,@rank:=@rank+1,@rank:=1) rank , @bak:=fiction_id bak FROM fiction_chapter ORDER BY fiction_id,chapter_sub_sort DESC ,chapter_sort DESC ) t WHERE t.rank < 2 limit 1,1000
@bak:=fiction_id 记录上一个的fiction_id 小说uuid ;
IF(@bak=fiction_id,@rank:=@rank+1,@rank:=1) 如果上一个的小说uuid和这个相等,rank=rank+1,否则rank重置为1
limit 1,1000 是因为数据量太大,先取1000条
sql逻辑: 因为是取最新章节,先在子查询中给每本小说的所有章节按照 卷倒叙,章节倒叙 排序,并且生成倒叙的序号。此时章节越大,编号越小 然后外部再查询一次,筛选rank<2的行,如果需要取其他条数,改值就行
2.在mybatis中查询
2.1 问题 mybatis里执行rank都为1
注意: sql语句不能直接放进 mybatis xml里用。需要改造一下 直接在mybatis中执行会出现 rank 值都是1的问题。
2.2修改
修改分2步: 1. 在jdbc连接中添加 允许同时执行多条语句:&allowMultiQueries=true
spring.datasource.url=jdbc:mysql://localhost:3306/mydata?serverTimezone=UTC&characterEncoding=utf-8&allowMultiQueries=true
2.在xml 里 sql之前设置用到的变量初始化 添加 : set @rank:=0,@bak:=’’;
<select id="selectLastChapter" resultType="fictionChapter">
set @rank:=0,@bak:='';
SELECT t.* FROM(
SELECT *
,IF(@bak=fiction_id,@rank:=@rank+1,@rank:=1) rank
,@bak:=fiction_id AS bak
FROM fiction_chapter
ORDER BY fiction_id,chapter_sub_sort DESC ,chapter_sort DESC
) t
<where>
t.rank <![CDATA[ < ]]> 2
</where>
limit 1,1000
</select>
结语: 1. 上面的解决办法是在dyc_dyc大佬帖子里找到解决办法的,感谢大佬 链接: https://ask.csdn.net/questions/4644962 2. 还有个办法是子查询count(*)比较的 但是我的数据量才23W就卡死了, 没有解决成功,就改成rank了
SELECT a.* FROM fiction_chapter a WHERE 1>
(SELECT COUNT(*) FROM fiction_chapter
WHERE fiction_id=a.fiction_id
AND chapter_sort>a.chapter_sort )
ORDER BY a.fiction_id,a.chapter_sort
3.优化 fiction_id和chapter_id虽然设置了索引,但是我那个sql查看执行计划却没有走索引,我只能limit限制下条数,23W条执行时间在3秒左右。这个sql办法还是有待优化,之后数据量还会加大会更卡。 水平不足,目前没解决,如果后续解决了再更新。
|