簡體   English   中英

如何在 SQL 中將 SELECT 行與 MIN(DateTime 列)、另一列分組和另一列 DISTINCT?

[英]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

我不知道studagent_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM