+-------------+---------+
| Column Name | Type |
+-------------+---------+
| student_id | int |
| subject | varchar |
| score | int |
| exam_date | varchar |
+-------------+---------+
(student_id, subject, exam_date) is the primary key for this table.
Each row contains information about a student's score in a specific subject on a particular exam date. score is between 0 and 100 (inclusive).
Write a solution to find the students who have shown improvement. A student is considered to have shown improvement if they meet both of these conditions:
Have taken exams in the same subject on at least two different dates
Their latest score in that subject is higher than their first score
Return the result tableordered bystudent_id,subjectinascending order.
Input:
Scores table:+------------+----------+-------+------------+| student_id | subject | score | exam_date |+------------+----------+-------+------------+|101| Math |70|2023-01-15||101| Math |85|2023-02-15||101| Physics |65|2023-01-15||101| Physics |60|2023-02-15||102| Math |80|2023-01-15||102| Math |85|2023-02-15||103| Math |90|2023-01-15||104| Physics |75|2023-01-15||104| Physics |85|2023-02-15|+------------+----------+-------+------------+Output:
+------------+----------+-------------+--------------+| student_id | subject | first_score | latest_score |+------------+----------+-------------+--------------+|101| Math |70|85||102| Math |80|85||104| Physics |75|85|+------------+----------+-------------+--------------+Explanation:
* Student 101in Math: Improved from 70 to 85* Student 101in Physics: No improvement(dropped from 65 to 60)* Student 102in Math: Improved from 80 to 85* Student 103in Math: Only one exam, not eligible
* Student 104in Physics: Improved from 75 to 85Result table is ordered by student_id, subject.
To find students who improved, we need to compare their first and latest scores in each subject. We can use window functions to get the first and last score per (student, subject), and then filter for those where the latest score is higher and there are at least two exams.
WITH ranked AS (
SELECT student_id, subject, score,
exam_date,
ROW_NUMBER() OVER (PARTITION BY student_id, subject ORDERBY exam_date) AS rn_first,
ROW_NUMBER() OVER (PARTITION BY student_id, subject ORDERBY exam_date DESC) AS rn_last,
COUNT(*) OVER (PARTITION BY student_id, subject) AS cnt
FROM Scores
)
SELECT student_id, subject
FROM (
SELECT student_id, subject,
MAX(CASEWHEN rn_first =1THEN score END) AS first_score,
MAX(CASEWHEN rn_last =1THEN score END) AS last_score,
MAX(cnt) AS cnt
FROM ranked
GROUPBY student_id, subject
) t
WHERE cnt >=2AND last_score > first_score
ORDERBY student_id, subject;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
WITH ranked AS (
SELECT student_id, subject, score,
exam_date,
ROW_NUMBER() OVER (PARTITION BY student_id, subject ORDERBY exam_date) AS rn_first,
ROW_NUMBER() OVER (PARTITION BY student_id, subject ORDERBY exam_date DESC) AS rn_last,
COUNT(*) OVER (PARTITION BY student_id, subject) AS cnt
FROM Scores
)
SELECT student_id, subject
FROM (
SELECT student_id, subject,
MAX(CASEWHEN rn_first =1THEN score END) AS first_score,
MAX(CASEWHEN rn_last =1THEN score END) AS last_score,
MAX(cnt) AS cnt
FROM ranked
GROUPBY student_id, subject
) t
WHERE cnt >=2AND last_score > first_score
ORDERBY student_id, subject;