[英]How to SELECT rows with MIN(DateTime column), GROUP by another column and DISTINCT by another column in SQL?
My table is:我的桌子是:
id ![]() |
student_id![]() |
exam_date![]() |
license![]() |
result![]() |
---|---|---|---|---|
1 ![]() |
101 ![]() |
01-11-2020 ![]() |
B2 ![]() |
FAILED![]() |
2 ![]() |
102 ![]() |
15-11-2020 ![]() |
A![]() |
PASSED![]() |
3 ![]() |
103 ![]() |
22-11-2020 ![]() |
D ![]() |
FAILED![]() |
4 ![]() |
101 ![]() |
01-10-2020 ![]() |
D ![]() |
PASSED![]() |
5 ![]() |
104 ![]() |
01-12-2020 ![]() |
A![]() |
PASSED![]() |
6 ![]() |
103 ![]() |
29-11-2020 ![]() |
D ![]() |
PASSED![]() |
7 ![]() |
101 ![]() |
01-12-2020 ![]() |
B2 ![]() |
PASSED![]() |
8 ![]() |
105 ![]() |
01-09-2020 ![]() |
B2 ![]() |
FAILED![]() |
9 ![]() |
104 ![]() |
01-11-2020 ![]() |
A![]() |
FAILED![]() |
10 ![]() |
105 ![]() |
01-11-2020 ![]() |
B2 ![]() |
PASSED![]() |
I need to select the results that would have the first result according to the exam date according to each student id and the license column.我需要 select 根据每个学生 ID 和许可证列,根据考试日期获得第一个结果的结果。 If the same student takes different license exam, these two results need to come up as well.
如果同一个学生参加不同的执照考试,这两个结果也需要拿出来。 But I need only one result row for each student id and license value.
但是对于每个学生 ID 和许可证值,我只需要一个结果行。
The result should look like this:结果应如下所示:
id ![]() |
student_id![]() |
exam_date![]() |
license![]() |
result![]() |
---|---|---|---|---|
1 ![]() |
101 ![]() |
01-11-2020 ![]() |
B2 ![]() |
FAILED![]() |
2 ![]() |
102 ![]() |
15-11-2020 ![]() |
A![]() |
PASSED![]() |
3 ![]() |
103 ![]() |
22-11-2020 ![]() |
D ![]() |
FAILED![]() |
4 ![]() |
101 ![]() |
01-10-2020 ![]() |
D ![]() |
PASSED![]() |
8 ![]() |
105 ![]() |
01-09-2020 ![]() |
B2 ![]() |
FAILED![]() |
9 ![]() |
104 ![]() |
01-11-2020 ![]() |
A![]() |
FAILED![]() |
I've done the research and queries and so far I only got 1 row for student_id although the student takes two different license examination.我已经完成了研究和查询,到目前为止,尽管学生参加了两次不同的执照考试,但我只得到了 1 行的 student_id。
The following is my query:以下是我的查询:
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
Thinking that you are grouping by student_id in this case is almost incorrect in this case.在这种情况下,认为您在这种情况下按 student_id 分组几乎是不正确的。 What are actually grouping by is student + license.
实际上分组的是学生+许可证。 Let's call this key combination
individual_license
.我们称这个组合键为
individual_license
。
Here's what the solution will look like:解决方案如下所示:
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;
This should work.这应该有效。
The problem with you original code is that it is missing a correlartion on the licences between the outer query and the subquery.您的原始代码的问题是它缺少外部查询和子查询之间的许可证相关性。 You would phrase it as:
您可以将其表述为:
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
I have no idea what stud
and agent_profile
are, so I removed the from the query.我不知道
stud
和agent_profile
是什么,所以我从查询中删除了。
That said, this is not the method I would recommend - a simple and efficient option is to filter with a subquery:也就是说,这不是我推荐的方法 - 一个简单而有效的选择是使用子查询进行过滤:
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
)
This can take advantage of an index on (student_id, license, exam_date)
.这可以利用
(student_id, license, exam_date)
上的索引。
Alternatively, you can use row_number()
, available in MySL 8.0:或者,您可以使用 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.