有一个需求,在答题主记录表里面根据用户答对题目数量(correct_answer)和答题时间(paper_time)进行排行。即:答对题目数量最大者排行最前,相同数量则根据时间最小来排行。
最开始想的思路:在用户表保存这两个字段,方便后期排序。但是无奈伙伴认为没必要,那就另辟蹊径。
直接上第一次的Sql:
SELECT appnickname,correct_answer,paper_time FROM (SELECT * FROM `nms_zpaper` ORDER BY correct_answer desc,paper_time asc LIMIT 1000000) a WHERE a.correct_answer>0 GROUP BY a.appuserid ORDER BY a.correct_answer DESC
之所以在子查询里面使用了limit限制条数,是因为高版本mysql,会对子查询进行优化,忽略order by这样也就失去了排序的意义。
通过查阅相关资料了解到MySql 5.7对子查询进行了优化,认为子查询中的order by可以进行忽略,只要Derived table里不包含如下条件就可以进行优化:
UNION clause
GROUP BY
DISTINCT
Aggregation
LIMIT or OFFSET
因此可以在子查询中使用group by pk分组,不让mysql进行子查询优化。修改之后的sql语句如下:
SELECT appnickname,correct_answer,paper_time FROM (SELECT * FROM `nms_zpaper` group by paper_id ORDER BY correct_answer desc,paper_time asc) a WHERE a.correct_answer>0 GROUP BY a.appuserid ORDER BY a.correct_answer DESC