因为窗口函数和聚合函数不能在同一个子查询里叠加使用,并且窗口函数的排序结果不能在同一个子查询底部进行where过滤,所以递进的CTE表达式是最方便的:
WITH info AS ( SELECT tid, uid, MAX(score) as maxs, MIN(score) as mins FROM ( SELECT DISTINCT tag as tid, r.id, r.uid, r.score FROM examination_info JOIN exam_record r USING(exam_id) ) temp GROUP BY tid, uid ORDER BY tid, maxs DESC, mins DESC, uid DESC ), rn AS( SELECT tid, uid, ROW_NUMBER() OVER (PARTITION BY tid ORDER BY tid, maxs DESC, mins DESC, uid DESC) AS ranking FROM info ) SELECT * FROM rn WHERE ranking <= 3
row_number里的order by的逻辑直接复制第一段cte里的就行