SQL新手在这里。我尝试过搜索,但无法找到这种情况。
对于特定考试,学生可以有多个记录(通过,失败,未显示,丢弃)。
results table
Student_ID Exam_ID Status Time_stamp
1 A Passed 2018-05-01
2 A Failed 2018-05-01
2 A Passed 2018-05-05
3 A No-Show 2018-05-01
3 A Failed 2018-05-05
4 A Passed 2018-05-01
4 A Failed 2018-05-25
如何构建我的SQL查询以显示已提交的学生列表,如果他们没有通过,则按日期显示最新状态。
例如,在示例数据中,student_id 1 =已通过,student_id 2 =已通过(一次通过记录=已通过)且student_id 3 =已失败(未通过记录,未通过后未通过),student_id 4 =已通过(一次通过)记录考试=通过,忽略以后失败)
到目前为止,我已尝试过这个 -
SELECT *
FROM results
WHERE Status = "Passed"
但这显然不包括未通过的状态。
真的很感激帮助。
答案 0 :(得分:1)
以下是使用union all
的一种方法:
select r.*
from results r
where r.status = 'Passed'
union all
select t.*
from results r
where not exists (select 1
from results r2
where r2.student_id = r.student_id and
r2.exam_id = r.exam_id and
r2.status = 'Passed'
) and
r.time_stamp = (select max(r2.time_stamp
from results r2
where r2.student_id = r.student_id and
r2.exam_id = r.exam_id
);
答案 1 :(得分:0)
以下链接几乎相同。使用一些策略,你会得到你的答案
答案 2 :(得分:0)
您也可以使用RANK:
执行此操作SELECT student_id, exam_id, status, time_stamp
FROM
(
SELECT *, RANK() OVER(PARTITION BY student_id ORDER BY time_stamp DESC) AS rnk
FROM t
) sub
WHERE status = 'Passed'
OR (rnk = 1
AND NOT EXISTS
(SELECT 1
FROM t t2
WHERE status = 'Passed'
AND t2.student_id = sub.student_id))
所以逻辑是:记录状态通过的记录或(1)测试是学生最近的测试和(2)学生没有通过考试。
答案 3 :(得分:0)
优化版
with t (Student_ID, Exam_ID, Status, Time_stamp) as
(
select 1, 'A', 'Passed', '2018-05-01' union all
select 2, 'A', 'Failed', '2018-05-01' union all
select 2, 'A', 'Passed', '2018-05-05' union all
select 3, 'A', 'No-Show', '2018-05-01' union all
select 3, 'A', 'Failed', '2018-05-05' union all
select 4, 'A', 'Passed', '2018-05-01' union all
select 4, 'A', 'Failed', '2018-05-25')
select * from (select *,row_number() over(PARTITION BY student_id,exam_id order by
case when status='Passed' then 1
when status='Failed' then 2
when status='No-Show' then 3 end, time_stamp desc) r from t) result where r=1