[英]How to SELECT rows with MIN(DateTime column), GROUP by another column and DISTINCT by another column in SQL?
我的桌子是:
ID | 学生卡 | 考试日期 | 执照 | 结果 |
---|---|---|---|---|
1 | 101 | 01-11-2020 | B2 | 失败的 |
2 | 102 | 15-11-2020 | 一个 | 通过 |
3 | 103 | 22-11-2020 | D | 失败的 |
4 | 101 | 01-10-2020 | D | 通过 |
5 | 104 | 01-12-2020 | 一个 | 通过 |
6 | 103 | 29-11-2020 | D | 通过 |
7 | 101 | 01-12-2020 | B2 | 通过 |
8 | 105 | 01-09-2020 | B2 | 失败的 |
9 | 104 | 01-11-2020 | 一个 | 失败的 |
10 | 105 | 01-11-2020 | B2 | 通过 |
我需要 select 根据每个学生 ID 和许可证列,根据考试日期获得第一个结果的结果。 如果同一个学生参加不同的执照考试,这两个结果也需要拿出来。 但是对于每个学生 ID 和许可证值,我只需要一个结果行。
结果应如下所示:
ID | 学生卡 | 考试日期 | 执照 | 结果 |
---|---|---|---|---|
1 | 101 | 01-11-2020 | B2 | 失败的 |
2 | 102 | 15-11-2020 | 一个 | 通过 |
3 | 103 | 22-11-2020 | D | 失败的 |
4 | 101 | 01-10-2020 | D | 通过 |
8 | 105 | 01-09-2020 | B2 | 失败的 |
9 | 104 | 01-11-2020 | 一个 | 失败的 |
我已经完成了研究和查询,到目前为止,尽管学生参加了两次不同的执照考试,但我只得到了 1 行的 student_id。
以下是我的查询:
SELECT scct_outer.id, scct_outer.stud_id, scct_outer.exam_date, scct_outer.license, scct_outer.result
FROM stud_cdl_comp_test AS scct_outer
INNER JOIN
(SELECT stud_id, MIN(exam_date) AS MinExamDate
FROM stud_cdl_comp_test AS scct
INNER JOIN stud AS s ON scct.stud_id = s.id
INNER JOIN agent_profile AS ap ON s.agent_profile_id = ap.id
GROUP BY stud_id) groupedscct
ON scct_outer.stud_id = groupedscct.stud_id
AND scct_outer.exam_date = groupedscct.MinExamDate
在这种情况下,认为您在这种情况下按 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;
这应该有效。
您的原始代码的问题是它缺少外部查询和子查询之间的许可证相关性。 您可以将其表述为:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.