简体   繁体   English

在SQL中查找与每个组中的第N个值相对应的行

[英]Finding the row corresponding to the Nth value in each group by in SQL

I have a table A as follows: 我有一个表A,如下所示:

name   course  grade
Bob      C1     12
Bob      C2     13
Bob      C3     23
Bob      C4     17 
James    C2     15
James    C6     27
Nick     C5    18
Nick     C1    16
Nick     C3    22
Nick     C2    32
Nick     C7    19

I want a query that can return the student name and the course number for each student corresponding to the 3rd highest grade for that student. 我想要一个查询,该查询可以返回每个学生的学生姓名和课程编号,对应于该学生的第三高年级。 For example, in the table above, the 3rd highest grade for Bob is 17 so the course number is C4. 例如,在上表中,鲍勃的第三高分是17,所以课程号是C4。 Also since James has fewer than 3 courses, his course should not be included in the query result. 同样,由于James的课程少于3门,因此不应将其课程包括在查询结果中。 In other words, the query result should show this: 换句话说,查询结果应显示为:

name course_id
Bob    C4
Nick   C7

What would be the query that can do that? 可以做到这一点的查询是什么?

In standard SQL one would do this using window functions: 在标准SQL中,可以使用窗口函数来做到这一点:

select name, course
from (
   select name, course, grade, 
          dense_rank() over (partition by name order by grade) as rnk
   from grades
) t
where rnk = 3

Online example: https://rextester.com/YOHZB50840 在线示例: https//rextester.com/YOHZB50840

Online example with MySQL: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=3f9ff551c89f6941dbf8e424e6dfda56 MySQL在线示例: https : //dbfiddle.uk/?rdbms=mysql_8.0&fiddle=3f9ff551c89f6941dbf8e424e6dfda56

use corelated subquery and row_number analytic function which support most dbms 使用支持大多数dbms的相关子查询和row_number分析函数

with cte as 
  ( select t1.* from table t1 where 
           exists ( select 1 from table t2 where t1.name=t2.name
                                 group by name 
                                 having count(distinct course)>=3
                  )
  ) , 
 cte2 as 
  (
select * ,row_number() over(partition by name order by grade asc) rn 
from cte
  ) select * from cte2 where rn=3

You can try using row_number() 您可以尝试使用row_number()

    select name, course
    from (
       select name, course, grade, 
              row_number() over (partition by name order by grade desc) as rn
       from grades
    ) t where rn = 3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM