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