mysql探索(一) 關於排重+排序的處理


問題

如何把數據按照某一個字段排重保留我們要的哪行記錄,然后以我們想要的順序排序好以后,查詢出來?

今天花了一整天的時間搞這個問題,本來以為是很簡單的問題就小瞧它了,結果發現網上一大堆錯誤答案,我也是醉了。。

 文章略長,主要講述的是我的探索(踩坑)過程,想要直接看解決方法的請拉到最后,拿走不謝~

過程

先說一下問題所在,比如說,現在有一個表,體溫測量。結構如下:

 

 假設我們每隔一段時間去給用戶測量一次體溫,那么同一個用戶就會產生多條記錄。現在我們想要查詢出每一個用戶最新一條測量數據,怎么查?

接下來我說說我的踩坑歷程:

是不是覺得很簡單,先分組,把重復的數據排掉:

select * from tplay_temperature_record group by user_id;

查詢結果:

 

 我去,不對啊,我想要的是最新的一條,id為51的那條數據才是我想要的啊,怎么給我返回了id為50的?不行,看來我得先排好序,再進行排重,(這個時候我以為group by拿的是第一條):

 第一步,先排序:

select * from tplay_temperature_record order by create_time desc;

看到結果,已經排好序了。

 

 然后我們用到子查詢去進行分組:

select * from (select * from tplay_temperature_record order by create_time) as a group by a.user_id;

結果:

 

 我去,不對啊,id為51的那條,咋又給我整沒了。

然后我開始在網上各種搜,在這個地址:https://blog.csdn.net/weixin_38450840/article/details/88836170

發現有人這樣說:

 

 

 

 

 卧槽,這樣子的嗎?原諒我年少無知,才疏學淺,那么我們試試,加上limit:

select * from (select * from tplay_temperature_record order by create_time limit 100) as a group by a.user_id;

結果:

 

 

 還是一樣,沒有任何改變,我不知道是不是mysql版本太低的原因,我用的是5.5.62,反正就是沒效果。

 

再看看其他大神的思路吧

於是我找到了這篇文章:https://blog.csdn.net/u012660464/article/details/78605078/

這篇文章的核心思想是:先分組,再排序。

對啊,我們想的是先排序再分組,如果反過來呢?

文章里說到:

 

 

 

按照他說的,寫一個:

SELECT *  FROM  (select * from tplay_temperature_record  order by user_id, create_time DESC) b 
GROUP BY b.user_id;

結果:

 

 

 啥情況,還是不對?接着往下翻,看到底下評論一堆叫苦連天的。。

 

 

 

 

 好吧,看來廣大網友和我一樣,沒從這篇文章中獲得什么~

 

解決

喜聞樂見的環節來了,在無數次的掙扎之后,終於獲得了正確的方法,也是參考了下面這篇文章,感謝大神!

地址:https://www.cnblogs.com/afei-happy/p/3783520.html

核心思想,兩個表的思想,就是先分組作為另一個表,然后進行子查詢,用user_id去關聯,對結果進行排序。

上步驟:

第一步,分組,排除重復,保留想要的哪一行記錄。這里我們是按照user_id排重,查詢時間最近的那條,就可以這樣寫:

 

SELECT
            user_id,
            max(create_time) max_day,
            temperature
        FROM
            tplay_temperature_record
        GROUP BY
            user_id

第二步,子查詢,把上述的查詢結果當成另一個表B,然后原表當成表A,用user_id去關聯,然后對查詢到的結果進行排序。

SELECT
    A.*
FROM
    tplay_temperature_record A,
    (
        SELECT
            user_id,
            max(create_time) max_day,
            temperature
        FROM
            tplay_temperature_record
        GROUP BY
            user_id
    ) B
WHERE
    A.user_id = B.user_id
AND A.create_time = B.max_day
ORDER BY
    A.create_time DESC

結果:

 

 

 

完美!

總結一下,這一類問題,看似簡單,其實復雜。

我自己感覺這個問題有兩個難點:

1、group by分組后如何保留自己想要的那一行數據?搭配聚合方法,或許有奇效

2、分組后的數據如何排序?其實不太好排序,為何不變通一下,分成兩個表,然后關聯一下查詢再排序呢?

除了這種方法,肯定有其他的,如果有其他方法的,希望在評論區大家一起討論下。

 

---------------------------------------------------------------------------------------------------------------------------------------

不好意思,找到一個更簡單的寫法:

SELECT
    *,
    max(create_time) max_day
FROM
    tplay_temperature_record
GROUP BY
    user_id
ORDER BY
    max_day DESC

 都不需要用到“兩個表”的思想。


免責聲明!

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



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