Skip to content

1280. Students and Examinations

Problem Statement

Table: Students

Column NameType
student_idint
student_namevarchar

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 NameType
subject_namevarchar

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 NameType
student_idint
subject_namevarchar

There is no primary key 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 has taken the exam of subject_name.

Instructions

  • 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

Input: Students table

student_idstudent_name
1Alice
2Bob
13John
6Alex

Input: Subjects table

subject_name
Math
Physics
Programming

Input: Examinations table

student_idsubject_name
1Math
1Physics
1Programming
2Programming
1Physics
1Math
13Math
13Programming
13Physics
2Math
1Math

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.

Submissions

sql
WITH AllCombinations AS (
    SELECT
        s.student_id,
        s.student_name,
        sub.subject_name
    FROM
        Students s
    CROSS JOIN
        Subjects sub
)
SELECT
    ac.student_id,
    ac.student_name,
    ac.subject_name,
    COALESCE(COUNT(e.subject_name), 0) AS attended_exams
FROM
    AllCombinations ac
LEFT JOIN
    Examinations e
ON
    ac.student_id = e.student_id
    AND ac.subject_name = e.subject_name
GROUP BY
    ac.student_id,
    ac.student_name,
    ac.subject_name
ORDER BY
    ac.student_id,
    ac.subject_name;

Explanations

PostgreSQL
Submitted by @noeyislearning
  • WITH AllCombinations AS (...): Create a Common Table Expression (CTE) named AllCombinations that contains all possible combinations of students and subjects.
    • SELECT s.student_id, s.student_name, sub.subject_name: Select the student_id and student_name from the Students table and the subject_name from the Subjects table.
    • FROM Students s CROSS JOIN Subjects sub: Perform a cross join between the Students and Subjects tables to get all possible combinations of students and subjects.
  • SELECT ac.student_id, ac.student_name, ac.subject_name, COALESCE(COUNT(e.subject_name), 0) AS attended_exams: Select the student_id, student_name, and subject_name from the AllCombinations CTE and count the number of times a student attended a particular exam. Use COALESCE to handle cases where a student did not attend any exam.
    • COALESCE(COUNT(e.subject_name), 0): Count the number of times a student attended a particular exam. If the count is NULL, replace it with 0.
  • FROM AllCombinations ac : Select from the AllCombinations CTE.
  • LEFT JOIN Examinations e: Perform a left join with the Examinations table on the student_id and subject_name columns to get the attended exams.
  • ON ac.student_id = e.student_id AND ac.subject_name = e.subject_name: Join the AllCombinations CTE with the Examinations table based on the student_id and subject_name.
  • GROUP BY ac.student_id, ac.student_name, ac.subject_name: Group the results by student_id, student_name, and subject_name.
  • ORDER BY ac.student_id, ac.subject_name: Order the results by student_id and subject_name.