sql题,选出每门科目前三名的学生

您所在的位置:网站首页 mysql求前三名 sql题,选出每门科目前三名的学生

sql题,选出每门科目前三名的学生

2024-04-16 14:00| 来源: 网络整理| 查看: 265

一、常见数据库

  关系型数据库:Oracle、DB2、SQLServer、MySQL

  非关系型数据库:MongoDB

  创建成绩表并插入数据:

create table StuScore(StuId int,Subject nvarchar(10),Score float); insert into StuScore values(1,'语文',70); insert into StuScore values(1,'数学',60); insert into StuScore values(1,'英语',90); insert into StuScore values(2,'语文',78); insert into StuScore values(2,'数学',67); insert into StuScore values(2,'英语',80); insert into StuScore values(3,'语文',89); insert into StuScore values(3,'数学',60); insert into StuScore values(3,'英语',97); insert into StuScore values(4,'语文',50); insert into StuScore values(4,'数学',67); insert into StuScore values(4,'英语',70); insert into StuScore values(5,'语文',79); insert into StuScore values(5,'数学',65); insert into StuScore values(5,'英语',79); insert into StuScore values(6,'语文',74); insert into StuScore values(6,'数学',56); insert into StuScore values(6,'英语',87);

二、Oracle完成

  用oracle的语言比较简洁,目前在 MSSQLServer、Oracle、DB2 等主流数据库中都提供了对开窗函数的支持,不过 MYSQL 暂时还未对开窗函数给予支持。

  1、开窗函数

  与聚合函数一样,开窗函数也是对行集组进行聚合计算,但是它不像普通聚合函数那样每组只返回一个值,开窗函数可以为每组返回多个值,因为开窗函数所执行聚合计算的行集组是窗口。

  开窗函数格式: 函数名(列) OVER(选项)

  OVER 关键字后的括号中还经常添加选项用以改变进行聚合运算的窗口范围。如果 OVER 关键字后的括号中的选项为空,则开窗函数会对结果集中的所有行进行聚合运算。

  例子:

  select fname, fcity, fsalary, count(*) over() 工资小于5000员工数

  from t_person

  where fsalary < 5000

    返回所有满足工资小于5000的记录,通过聚合函数count计算这些记录的个数。

  如果用MySQL实现就比较麻烦:

  select fname, fcity,fsalary,

  (select count(*) from t_person where fsalary < 5000) 工资少于5000员工总数

  from t_person

  where fsalary < 5000;

  结果如下:

  2、partition by

  开窗函数的 OVER 关键字后括号中的可以使用 PARTITION BY 子句来定义行的分区来供进行聚合计算。类似于GROUP BY,但与 GROUP BY 子句不同是,PARTITION BY 子句创建的分区是独立于结果集的,创建的分区只是供进行聚合计算的,而且不同的开窗函数所创建的分区也不互相影响。即使用Partiton by字句定义行的分区或组,可以用paritition by对定义的行组计算聚集(当遇到新组的时候复位),并返回每个值(每个组中的每个成员),而不是一个用一个组表示表中的这个值的所有实例。下面这个例子具体的展现了它的作用:

 

   注意:原表中的每一行都会返回,并得出他对应分组后的聚合计算值。

  3、row_number()

  除了可以在开窗函数中使用COUNT()、SUM()、MIN()、MAX()、AVG()等这些聚合函数,还可以在开窗函数中使用一些高级的函数,有些函数同时被DB2和Oracle同时支持,比如RANK()、DENSE_RANK()、ROW_NUMBER(),而有些函数只被Oracle支持,比如RATIO_TO_REPORT()、NTILE()、LEAD()、LAG()、FIRST_VALUE()、LAST_VALUE()。

  row_number():从1开始,为每一条分组记录返回一个数字,返回的主要是“行”的信息,并没有排名

 语法:ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2)

 功能:表示根据COL1分组,在分组内部根据 COL2排序,而这个值就表示每组内部排序后的顺序编号(组内连续的唯一的)

  4、order by

  下面这个例子很好的说明了order by 在窗口函数中的作用:

等价于:

 

  5、解决问题

  语法:  

  select * from

  (select *,row_number() over(partition by Subject order by Score desc) rn

  from StuScore)

  where rn



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3