SELECT * FROM ( SELECT tag AS tid, uid, ROW_NUMBER() OVER (PARTITION BY tag ORDER BY MAX(score) desc ,MIN(score) DESC,uid DESC) AS ranking FROM examination_info t JOIN exam_record t1 USING (exam_id) GROUP BY tag, uid ) t WHERE ranking <= 3
知识点:
1、窗口函数的执行顺序是在group by之后的,所以他是对最后的结果进行再计算
2、虽有partition by但是这个和groupby并不冲突,partitionby是根据运算结果后的表,在进行分组计算的
3、groupby和其他的聚合计算一样,虽然结果产生了聚合,但是聚合内的信息还是保留的
4、在有聚合的情况下,其中max(score)返回的是确定的值,且类似形成新的表,按聚合方式进行计算。如果 order by score 不聚合,因为mysql的计算逻辑,在groupby下是不确定会返回分组内的哪个值。
所以平常的窗口函数并不与groupby同时出现,但是一旦出现,orderby中就需要跟聚合内容。
5、如果不想这样,觉得不好理解,可以在from表中利用子查询,先对表进行一次处理。如下面的答案
select tag,uid,ranking from ( select *,row_number() over(partition by tag order by max_s desc,min_s desc,uid desc) as ranking from ( select tag,uid,max(score) as max_s ,min(score) as min_s from exam_record t left join examination_info using(exam_id) group by tag,uid)t1)t2 where ranking <=3