Leecode_SQL50_1280. Students and Examinations

  1. Students and Examinations

Problem description

Table: Students

±--------------±--------+
| Column Name | Type |
±--------------±--------+
| student_id | int |
| student_name | varchar |
±--------------±--------+
student_id is the primary key (column with unique values) for this table.
Each row of this table contains the ID and the name of one student in the school.

Table: Subjects

±-------------±--------+
| Column Name | Type |
±-------------±--------+
| subject_name | varchar |
±-------------±--------+
subject_name is the primary key (column with unique values) for this table.
Each row of this table contains the name of one subject in the school.

Table: Examinations

±-------------±--------+
| Column Name | Type |
±-------------±--------+
| student_id | int |
| subject_name | varchar |
±-------------±--------+
There is no primary key (column with unique values) for this table. It may contain duplicates.
Each student from the Students table takes every course from the Subjects table.
Each row of this table indicates that a student with ID student_id attended the exam of subject_name.

Write a solution to find the number of times each student attended each exam.

Return the result table ordered by student_id and subject_name.

The result format is in the following example.

Example 1:

Input:
Students table:
±-----------±-------------+
| student_id | student_name |
±-----------±-------------+
| 1 | Alice |
| 2 | Bob |
| 13 | John |
| 6 | Alex |
±-----------±-------------+
Subjects table:
±-------------+
| subject_name |
±-------------+
| Math |
| Physics |
| Programming |
±-------------+
Examinations table:
±-----------±-------------+
| student_id | subject_name |
±-----------±-------------+
| 1 | Math |
| 1 | Physics |
| 1 | Programming |
| 2 | Programming |
| 1 | Physics |
| 1 | Math |
| 13 | Math |
| 13 | Programming |
| 13 | Physics |
| 2 | Math |
| 1 | Math |
±-----------±-------------+
Output:

student_idstudent_namesubject_nameattended_exams
1AliceMath3
1AlicePhysics2
1AliceProgramming1
2BobMath1
2BobPhysics0
2BobProgramming1
6AlexMath0
6AlexPhysics0
6AlexProgramming0
13JohnMath1
13JohnPhysics1
13JohnProgramming1

Explanation:
The result table should contain all students and all subjects.
Alice attended the Math exam 3 times, the Physics exam 2 times, and the Programming exam 1 time.
Bob attended the Math exam 1 time, the Programming exam 1 time, and did not attend the Physics exam.
Alex did not attend any exams.
John attended the Math exam 1 time, the Physics exam 1 time, and the Programming exam 1 time.

My solution

The first WITH:

SELECT * 
    FROM Students s
        CROSS JOIN Subjects su

用 CROSS JOIN 获取所有学生和科目的组合,不用有相同的列来 JOIN ON.
Output:

student_idstudent_namesubject_name
1AliceProgramming
1AlicePhysics
1AliceMath
2BobProgramming
2BobPhysics
2BobMath
13JohnProgramming
13JohnPhysics
13JohnMath
6AlexProgramming
6AlexPhysics
6AlexMath

The second WITH:

    SELECT student_id, subject_name, COUNT(*) AS attended_exams
    FROM Examinations
    GROUP BY student_id, subject_name

Output:

student_idsubject_nameattended_exams
1Math3
1Physics2
1Programming1
2Programming1
13Math1
13Programming1
13Physics1
2Math1

Combine them:

WITH a AS (
    SELECT * 
    FROM Students s
        CROSS JOIN Subjects su
), 
j AS (
    SELECT student_id, subject_name, COUNT(*) AS attended_exams
    FROM Examinations
    GROUP BY student_id, subject_name
)
SELECT a.student_id, a.student_name, a.subject_name, COALESCE(j.attended_exams, 0) AS attended_exams
FROM a
LEFT JOIN j
    ON a.student_id = j.student_id
        AND a.subject_name = j.subject_name
ORDER BY a.student_id ASC, a.subject_name ASC

注意一定要选择 a.subject_name!因为只有这个表是全的。若选择错了,有人的 subject_name 会是 null.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值