我的表是:
id | student_id | exam_date许可证 | 结果[/tr>||
---|---|---|---|---|
1 | 101 | 01-11-2020 | B2 | 失败|
2 | 102 | 15-11-2020 | ||
3 | 103 | 22-11-2020D | 失败 | |
4 | 101 | 10-2020 | D | 通过|
5 | 104 | 01-12-2020 | ||
6 | 103 | 29-11-2020|||
7 | 101 | 1020年12月1日 | >td>B2通过||
8 | 105 | >01-09-2020 | B2 | 失败 |
9 | 104 | 01-11-2020 | A失败||
10 | 105 | 01-11-2020 | B2 | 已通过
原始代码的问题在于,它在外部查询和子查询之间的许可证上缺少相关性。你会把它说成:
select s.*
from stud_cdl_comp_test s
inner join (
select student_id, licence, min(exam_date) as minexamdate
from stud_cdl_comp_test as scct
group by stud_id, licence
) s1 on s1.student_id = s.student_id and s1.license = s.license and s1.minexamdate = s.date
我不知道stud
和agent_profile
是什么,所以我从查询中删除了。
也就是说,这不是我推荐的方法——一个简单有效的选择是使用子查询进行过滤:
select *
from stud_cdl_comp_test s
where s.exam_date = (
select min(s1.exam_date)
from stud_cdl_comp_test s1
where s1.student_id = s.student_id and s1.license = s.license
)
这可以利用(student_id, license, exam_date)
上的索引。
或者,您可以使用MySL 8.0:中提供的row_number()
select *
from (
select s.*,
row_number() over(partition by student_id, licence order by exam_date) rn
from stud_cdl_comp_test s
) s
where rn = 1
在这种情况下,认为您是按student_id分组的想法在这种情况中几乎是不正确的。实际分组依据是学生+许可证。让我们把这个组合键称为individual_license
。
以下是解决方案:
SELECT
st.id,
st.stud_id,
st.exam_date,
st.license,
st.result
FROM stud_cdl_comp_test AS st
INNER JOIN
(SELECT
MIN(exam_date) AS min_date,
st_inner.student_id,
st_inner.license
FROM stud_cdl_comp_test AS st_inner
GROUP BY st_inner.student_id, st_inner.license
) grouped_inner
ON grouped_inner.student_id = st.student_id
AND grouped_inner.license = st.license
AND grouped_inner.min_date = st.exam_date;
这应该行得通。