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()的情况。

  • 相关阅读:
    Linux ,Ubuntu 分区建议大小
    [No000019A]【波浪理论精典教学课程】
    CS(计算机科学)知识体
    如何量化考核技术人的KPI?
    Linux系统的命令应该如何记?
    数学和物理太难?这些 GIF 让你秒懂抽象概念
    加密数字货币的 7 个致命悖论
    量子力学中,全体自然数之和是负十二分之一,物理意义是什么?
    30岁左右的人,来谈谈你犯了哪些错误?
    一篇文章学懂Shell脚本,最简明的教程在这里
  • 原文地址:https://www.cnblogs.com/itjeff/p/5456004.html
Copyright © 2011-2022 走看看