美文网首页
Leetcode1412.查找成绩处于中游的学生(困难)

Leetcode1412.查找成绩处于中游的学生(困难)

作者: kaka22 | 来源:发表于2020-07-25 23:43 被阅读0次

    题目
    Table: Student

    +---------------------+---------+
    | Column Name         | Type    |
    +---------------------+---------+
    | student_id          | int     |
    | student_name        | varchar |
    +---------------------+---------+
    

    student_id is the primary key for this table.
    student_name is the name of the student.

    Table: Exam

    +---------------+---------+
    | Column Name   | Type    |
    +---------------+---------+
    | exam_id       | int     |
    | student_id    | int     |
    | score         | int     |
    +---------------+---------+
    

    (exam_id, student_id) is the primary key for this table.
    Student with student_id got score points in exam with id exam_id.

    A "quite" student is the one who took at least one exam and didn't score neither the high score nor the low score.

    Write an SQL query to report the students (student_id, student_name) being "quiet" in ALL exams.

    Don't return the student who has never taken any exam. Return the result table ordered by student_id.

    The query result format is in the following example.

    Student table:

    +-------------+---------------+
    | student_id  | student_name  |
    +-------------+---------------+
    | 1           | Daniel        |
    | 2           | Jade          |
    | 3           | Stella        |
    | 4           | Jonathan      |
    | 5           | Will          |
    +-------------+---------------+
    

    Exam table:

    +------------+--------------+-----------+
    | exam_id    | student_id   | score     |
    +------------+--------------+-----------+
    | 10         |     1        |    70     |
    | 10         |     2        |    80     |
    | 10         |     3        |    90     |
    | 20         |     1        |    80     |
    | 30         |     1        |    70     |
    | 30         |     3        |    80     |
    | 30         |     4        |    90     |
    | 40         |     1        |    60     |
    | 40         |     2        |    70     |
    | 40         |     4        |    80     |
    +------------+--------------+-----------+
    

    Result table:

    +-------------+---------------+
    | student_id  | student_name  |
    +-------------+---------------+
    | 2           | Jade          |
    +-------------+---------------+
    

    For exam 1: Student 1 and 3 hold the lowest and high score respectively.
    For exam 2: Student 1 hold both highest and lowest score.
    For exam 3 and 4: Studnet 1 and 4 hold the lowest and high score respectively.
    Student 2 and 5 have never got the highest or lowest in any of the exam.
    Since student 5 is not taking any exam, he is excluded from the result.
    So, we only return the information of Student 2.

    生成数据

    CREATE TABLE Student3(
    student_id         INT,     
    student_name       VARCHAR(20));
    
    CREATE TABLE Exam(
    exam_id       INT,
    student_id    INT,
    score         INT);
    
    INSERT INTO Student3 VALUE(1, 'Daniel'),(2, 'Jade'),(3, 'Stella'),(4, 'Jonathan'),(5, 'Will');
    
    INSERT INTO Exam VALUE(10, 1, 70),(10, 2, 80),(10, 3, 90),(20, 1, 80),
    (30, 1, 70),(30, 3, 80),(30, 4, 90),
    (40, 1, 60),(40, 2, 70),(40, 4, 80);
    

    解答
    就是选出在每一门课中都没有取到最高分也没有取到最低分的同学 但是他得参加考试
    对exam_id进行分组 可以得到最高分和最低分
    用二元in可以选出得到过最低分和最高分的同学
    在exam中排除以上的同学即可
    最后和Student 表左连接

    先选出最高分和最低分

    SELECT E.`exam_id`, MAX(E.`score`) AS max_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`
    UNION
    SELECT E.`exam_id`, MIN(E.`score`) AS min_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`;
    

    再选出得到过最高分或最低分的同学

    SELECT DISTINCT EEE.`student_id`
    FROM Exam AS EEE
    WHERE (EEE.`exam_id`, EEE.`score`) IN (SELECT E.`exam_id`, MAX(E.`score`) AS max_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`
    UNION
    SELECT E.`exam_id`, MIN(E.`score`) AS min_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`);
    

    排除以上的同学

    SELECT DISTINCT EE.`student_id`
    FROM Exam AS EE
    WHERE EE.`student_id` NOT IN (SELECT DISTINCT EEE.`student_id`
    FROM Exam AS EEE
    WHERE (EEE.`exam_id`, EEE.`score`) IN (SELECT E.`exam_id`, MAX(E.`score`) AS max_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`
    UNION
    SELECT E.`exam_id`, MIN(E.`score`) AS min_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`));
    

    最后两表连接即可 左连接

    SELECT S.`student_id`, S.`student_name`
    FROM (SELECT DISTINCT EE.`student_id`
    FROM Exam AS EE
    WHERE EE.`student_id` NOT IN (SELECT DISTINCT EEE.`student_id`
    FROM Exam AS EEE
    WHERE (EEE.`exam_id`, EEE.`score`) IN (SELECT E.`exam_id`, MAX(E.`score`) AS max_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`
    UNION
    SELECT E.`exam_id`, MIN(E.`score`) AS min_sc
    FROM Exam AS E
    GROUP BY E.`exam_id`))) AS tmp
    LEFT JOIN Student3 AS S
    ON tmp.student_id = S.`student_id`;
    

    相关文章

      网友评论

          本文标题:Leetcode1412.查找成绩处于中游的学生(困难)

          本文链接:https://www.haomeiwen.com/subject/qefvlktx.html