找出在每个学期和每个课程中得分最高的学生的姓名吗?

时间:2018-10-04 10:28:36

标签: sql oracle oracle-sqldeveloper

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

我一直以来都觉得这里缺少联系,无法获得在每学期和每门课程中得分最高的学生姓名,我错了吗?还是缺少什​​么?预先感谢。

表的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;

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

我喜欢这个选项...

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;