编写一个查询,该查询将获取每个科目中排名前 3 的学生姓名以及他们的分数

Posted

技术标签:

【中文标题】编写一个查询,该查询将获取每个科目中排名前 3 的学生姓名以及他们的分数【英文标题】:write a query which will fetch the top 3 students names in each subject along with the marks they score 【发布时间】:2017-10-07 11:30:20 【问题描述】:

我是 PL/SQL 新手,需要查询以下场景:

2 个表:第一个带有卷号、名称的表 第二卷没有,主题 n 标记 需要编写一个查询来获取每个科目中排名前 3 的学生姓名以及他们的分数

我已经写了下面的查询,但它没有获取正确的结果:

SELECT TABLE1.NAME, MAX(TABLE2.MARKS) 
FROM 
TABLE1 
INNER JOIN 
TABLE2
ON TABLE1.ROLL_NO = TABLE2.ROLL_NO
GROUP BY SUB
ORDER BY TABLE2.MARKS
HAVING ROWNUM <3

下表是数据:

CREATE TABLE STUDENT ( ROLL_NO INT PRIMARY KEY, NAME VARCHAR(20));
INSERT INTO STUDENT VALUES (1,'NIKHIL');
INSERT INTO STUDENT VALUES (2,'VARUN');
INSERT INTO STUDENT VALUES (3,'NISHANT');
INSERT INTO STUDENT VALUES (4,'VISHAL');
INSERT INTO STUDENT VALUES (5,'GOURAV');
INSERT INTO STUDENT VALUES (6,'HEMANT');
INSERT INTO STUDENT VALUES (7,'SHUBHAM');
INSERT INTO STUDENT VALUES (8,'DHAWAN');
INSERT INTO STUDENT VALUES (9,'GAUTAM');


CREATE TABLE MARKS ( ROLL_NO INT, SUBJECT VARCHAR(20), MARKS INT);
INSERT INTO MARKS VALUES('1','MATHS','92');
INSERT INTO MARKS VALUES('1','SCIENCE','80');
INSERT INTO MARKS VALUES('1','ENGLISH','98');
INSERT INTO MARKS VALUES('1','HINDI','81');
INSERT INTO MARKS VALUES('2','MATHS','89');
INSERT INTO MARKS VALUES('2','SCIENCE','100');
INSERT INTO MARKS VALUES('2','ENGLISH','81');
INSERT INTO MARKS VALUES('2','HINDI','82');
INSERT INTO MARKS VALUES('3','MATHS','98');
INSERT INTO MARKS VALUES('3','SCIENCE','92');
INSERT INTO MARKS VALUES('3','ENGLISH','88');
INSERT INTO MARKS VALUES('3','HINDI','83');
INSERT INTO MARKS VALUES('4','MATHS','88');
INSERT INTO MARKS VALUES('4','SCIENCE','82');
INSERT INTO MARKS VALUES('4','ENGLISH','85');
INSERT INTO MARKS VALUES('4','HINDI','97');
INSERT INTO MARKS VALUES('5','MATHS','94');
INSERT INTO MARKS VALUES('5','SCIENCE','90');
INSERT INTO MARKS VALUES('5','ENGLISH','97');
INSERT INTO MARKS VALUES('5','HINDI','89');
INSERT INTO MARKS VALUES('6','MATHS','89');
INSERT INTO MARKS VALUES('6','SCIENCE','82');
INSERT INTO MARKS VALUES('6','ENGLISH','84');
INSERT INTO MARKS VALUES('6','HINDI','85');
INSERT INTO MARKS VALUES('7','MATHS','82');
INSERT INTO MARKS VALUES('7','SCIENCE','100');
INSERT INTO MARKS VALUES('7','ENGLISH','92');
INSERT INTO MARKS VALUES('7','HINDI','98');
INSERT INTO MARKS VALUES('8','MATHS','99');
INSERT INTO MARKS VALUES('8','SCIENCE','91');
INSERT INTO MARKS VALUES('8','ENGLISH','86');
INSERT INTO MARKS VALUES('8','HINDI','82');
INSERT INTO MARKS VALUES('9','MATHS','100');
INSERT INTO MARKS VALUES('9','SCIENCE','95');
INSERT INTO MARKS VALUES('9','ENGLISH','81');
INSERT INTO MARKS VALUES('9','HINDI','81');

【问题讨论】:

与示例数据共享表。这样你会得到更好的帮助。解决方案涉及 mysql 的用户变量,因为 ROWNUM 在 MySQL 中不存在 如果您是 PL/SQL 新手,为什么要标记 MySQL? 我相信您使用的是 Oracle 我已经更新了上面的表格数据 【参考方案1】:

您可以像这样使用 ROW_NUMBER 窗口函数。

SELECT
 *
FROM ( 

  SELECT
     MARKS.ROLL_NO
   , MARKS.SUBJECT
   , MARKS.MARKS 
   , ROW_NUMBER() OVER (PARTITION BY ROLL_NO ORDER BY MARKS DESC) AS rank 
  FROM
   MARKS
) MARKS_RANKED
INNER JOIN
 STUDENT
ON
 MARKS_RANKED.ROLL_NO = STUDENT.ROLL_NO
 WHERE 
  rank <= 3

演示http://www.sqlfiddle.com/#!4/05776/41

【讨论】:

以上是关于编写一个查询,该查询将获取每个科目中排名前 3 的学生姓名以及他们的分数的主要内容,如果未能解决你的问题,请参考以下文章

sql 语句编写 查询参加全部科目考试的学生及其成绩 201601 张三 语文 82

获取每组最高/最小 <whatever> 的记录

用sql语句,查询每个班级成绩排名前三名的学生姓名

用sql语句,查询每个班级成绩排名前三名的学生姓名

Oracle中排名排序函数,ROW_NUMBERRANKDENSE_RANKNTILE

SQL四大排名函数(ROW_NUMBERRANKDENSE_RANKNTILE)