zoukankan      html  css  js  c++  java
  • 查询出各个学科的前3名的同学信息的Sql

    查找各个学科的成绩前3名的学生信息Sql,有2种方法,一种是利用sql的row_number() over()函数,另一种是用子查询,

    表设计如下

    如果不考虑各个学科的成绩有并列的情况的话,有如下两种方法进行查询,

    1. ROW_NUMBER() OVER()函数

    select * from (
    select ROW_NUMBER() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest
    ) as a
    where rownum < 4
    order by CourseName

    结果如下图

    2. 子查询

    select * from MyTest m
    where id in (select top 3 id from MyTest n where n.CourseName = m.CourseName order by Score desc)
    order by CourseName,Score desc

    结果如下图

    可以看出,当各个学科的前三名所得分数没有相同时,以上2种方法都可以,但如果某个科目有相同的分数时,

    所得结果就会出现不一致的情况,如张三和刘德华的数学分数都是70分,第一个查出的前三名包括刘德华,而第二个查询前三名却包括张三

    要解决以上问题,可以运用Sql的 rank() OVER()或dense_rank() OVER()函数进行查询,

    具体是使用这2个方法中的哪一个要看具体的结果需求,可以先了解下这2个函数的具体用法再决定用哪个更合适,

    我这里以 rank() OVER() 函数为例,解决方法如下:

    1.

    select * from (
    select rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest
    ) as a
    where rownum < 4
    order by CourseName

    结果如下图

    这时就可以看到数学一课中,得分都为70的刘德华和张三都被查询到了

    如果使用dense_rank() OVER()函数,语句如下

    select * from (
    select dense_rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest
    ) as a
    where rownum < 4
    order by CourseName

    结果如下图

    原因在于dense_rank() OVER()与 rank() OVER()对于重复的数据编号时的处理方式不同,

    rank()碰到重复的记录时编码下一个记录时会跳数字,而dense_rank() OVER()则不会,

    如用rank() OVER()如下

    select rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

    结果如下图

    注意看数学学科的按分数排名的规则

    如果使用dense_rank() OVER(),

    select dense_rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

    结果如下图

    另外,对于子查询方式,对于重复分数的记录,如果我们查询各个学科的前3名时也想查询出来,可以使用以下改进的语句,如

    with a as (
    select distinct CourseName,Score from MyTest m
    where id in (select top 3 id from MyTest n where n.CourseName = m.CourseName order by Score desc)
    --order by CourseName,Score desc
    )
    select m.*
    from MyTest m join a n
    on m.CourseName = n.CourseName
    and m.Score = n.Score
    order by CourseName,Score desc

    结果如下图

    这种写法类似于使用Sql函数rank() OVER()的情况。

  • 相关阅读:
    LSMW TIPS
    Schedule agreement and Delfor
    Running VL10 in the background 13 Oct
    analyse idoc by creation date
    New Journey Prepare
    EDI error
    CBSN NEWS
    Listen and Write 18th Feb 2019
    Microsoft iSCSI Software Target 快照管理
    通过 Microsoft iSCSI Software Target 提供存储服务
  • 原文地址:https://www.cnblogs.com/itjeff/p/5456004.html
Copyright © 2011-2022 走看看