找出在每门 sem 和每门课程中得分最高的学生的名字?

Posted

技术标签:

【中文标题】找出在每门 sem 和每门课程中得分最高的学生的名字?【英文标题】:Find the name of the student who has scored highest marks in every sem and each course? 【发布时间】:2018-10-04 10:28:36 【问题描述】:

有 2 个表,即学生和记分卡,我为每个表编写了可创建脚本以及插入语句中的一些示例数据。

我觉得这里缺少一些链接,并且无法获得在每门 sem 和每门课程中得分最高的学生姓名,是我错了还是缺少了什么?提前致谢。

表的sql脚本

CREATE TABLE student (
    name     VARCHAR2(100),
    regno    NUMBER(20) PRIMARY KEY,
    dob      DATE,
    course   VARCHAR2(200)
);

INSERT INTO student VALUES (
    'S1',
    1001,
    '5-04-2000',
    'computer'
);

INSERT INTO student VALUES (
    'S2',
    1002,
    '8-04-2010',
    'Electronics'
);

INSERT INTO student VALUES (
    'S3',
    1003,
    '2-04-2100',
    'management'
);

INSERT INTO student VALUES (
    'S4',
    1004,
    '28-05-2000',
    'Electronics'
);

INSERT INTO student VALUES (
    'S5',
    1005,
    '2-04-2000',
    'computer'
);

COMMIT;

CREATE TABLE markscard (
    regno    NUMBER(20)
        REFERENCES student ( regno ),
    sem      VARCHAR2(100),
    sub1     NUMBER(20),
    sub2     NUMBER(20),
    sub3     NUMBER(20),
    tot      NUMBER(20),
    avge     NUMBER(20),
    result   VARCHAR2(200)
);

INSERT INTO markscard VALUES (
    1001,
    1,
    30,
    30,
    30,
    90,
    30,
    'pass'
);

INSERT INTO markscard VALUES (
    1002,
    1,
    10,
    10,
    10,
    100,
    10,
    'fail'
);

INSERT INTO markscard VALUES (
    1003,
    2,
    100,
    100,
    100,
    300,
    100,
    'distinction'
);

INSERT INTO markscard VALUES (
    1004,
    2,
    20,
    20,
    20,
    60,
    20,
    'pass'
);

INSERT INTO markscard VALUES (
    1005,
    1,
    30,
    30,
    30,
    100,
    30,
    'pass'
);

COMMIT;

这是我尝试过但无法成功获取学生姓名的查询,因为我觉得缺少一些链接。

SELECT
    MAX(hightest_score),
    course_name,
    sem
FROM
    (
        SELECT
            MAX(markscard.tot) AS hightest_score,
            student.course   AS course_name,
            markscard.sem    AS sem,
            student.name     AS sname
        FROM
            markscard,
            student
        WHERE
            student.regno = markscard.regno
        GROUP BY
            student.course,
            markscard.sem,
            student.name
    )
GROUP BY
    course_name,
    sem;

【问题讨论】:

【参考方案1】:

首先,学会使用正确、明确、标准 JOIN 语法。其次,最好的方法是使用窗口函数:

SELECT sm.*
FROM (SELECT s.course as course_name, mc.sem, s.name, mc.tot,
              MAX(tot) OVER (PARTITION BY s.course, mc.sem) as max_tot
      FROM markscard mc JOIN
           student s
           ON s.regno = mc.regno
     ) sm
WHERE tot = max_tot;

【讨论】:

嘿@gordon-linoff 我在你的解决方案上得到了 904【参考方案2】:

我喜欢这个选项...

WITH RANKED_DATA
     AS (SELECT S.REGNO,
                S.NAME,
                S.COURSE,
                M.SEM,
                M.TOT,
                RANK () OVER (PARTITION BY S.COURSE, M.SEM ORDER BY M.TOT DESC) AS RK
           FROM MARKSCARD M INNER JOIN STUDENT S ON (M.REGNO = S.REGNO))
SELECT *
  FROM RANKED_DATA
 WHERE RK = 1;

【讨论】:

以上是关于找出在每门 sem 和每门课程中得分最高的学生的名字?的主要内容,如果未能解决你的问题,请参考以下文章

用一条sql语句查询出“每门”课程都大于80分的学生姓名

这个程序如何返回最高分的学生号和课程号?用函数做。

我怎样才能找到每门课程的学生ID最高分

SQL查询每门课程最高分学生的学号,课程号,成绩

sql,查询每门课程最高分的学生的学号,课程号,成绩。再一张表里

C语言试题练习:输入5个学生5门课的成绩,分别用函数求:1.每个学生平均分;2.每门课的平均分;3.找出所有分数中最高分