SQL中group by問題


在使用sql語句中,我們常常使用group by加聚合函數來分組並聚合,從而實現某些需求。然而,不正確地使用group by和聚合函數,會帶來非常隱晦的問題。

有這樣一個需求:對表進行分組后找出用戶首次獲得最高分數的那條記錄的全部信息。

為此,我創建了一張記錄用戶闖關信息的表,記錄了用戶在不同課程領域的不同關卡下獲得的分數信息:

pass_log表

最開始我覺得很簡單,sql是這樣寫的:

select pl.id, pl.user_id, pl.course_id, pl.pass_id, max(pl.total_score)
from pass_log pl
group by pl.user_id, pl.course_id, pl.pass_id;

結果是這樣的:

 大家發現端倪沒有?分組和聚合的結果都是對的,但是id卻是錯的,正確的id應該分別是3、5啊!但是為什么取的是1、4呢?因為它取的是分組后的第一條記錄的id!那應該怎么改過來呢?我的想法是先獲取分組后的信息和最高分,再和原表進行內關聯:

select p.id, p.user_id, p.course_id, p.pass_id, p.total_score
from pass_log p
join (
    select pl.user_id, pl.course_id, pl.pass_id, max(pl.total_score) maxTotalScore
    from pass_log pl
    group by pl.user_id, pl.course_id, pl.pass_id) t
on p.user_id = t.user_id and p.course_id = t.course_id and p.pass_id = t.pass_id
where p.total_score = maxTotalScore
group by p.user_id, p.course_id, p.pass_id;

我在最外層又加group by的原因是用戶可能在同一個關卡里獲得多次最高分,而我只想要首次獲得最高分數的那條記錄,最后結果是正確的,如圖:

后來我想數據查出來的都是錯的,為什么mysql不報錯呢?這樣不是坑我?后來發現還真的會出現報錯的情況,執行sql觀察:

select @@global.sql_mode;

如果結果中含有ONLY_FULL_GROUP_BY的話,執行我的第一條sql語句就會報錯,想要不報錯的話就要把pl.id改為any_value(pl.id),但是結果還是取分組后的第一個id,並不是我想要的結果。

其實我最后想表達的是,如果你的group by語句在一個環境下沒問題,但是在其它環境下就報異常,那會不會是你group by用錯了?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM