MySqlGroupby函數(shù)怎么正確使用

這篇文章主要介紹了MySQL Group by函數(shù)怎么正確使用的相關(guān)知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇MySql Group by函數(shù)怎么正確使用文章都會有所收獲,下面我們一起來看看吧。

站在用戶的角度思考問題,與客戶深入溝通,找到招遠網(wǎng)站設(shè)計與招遠網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名與空間、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務覆蓋招遠地區(qū)。

在使用分組函數(shù)時, 進行結(jié)果集篩選, 遇到的一些問題以及解決辦法

1. 應用場景

有兩張表

文章表(一對多留言表) t_posts:      
oid, posts_name    
留言表(多對一文章表) t_comment:    
oid, posts_id, msg_content, create_time

2.需求分析

查詢每個文章的最新回復內(nèi)容

3.SQL編寫

select 
  tp.oid,
  tp.posts_name,
  tc.msg_content,
  tc.create_time
from t_posts tp 
left join t_comment tc on tp.oid = tc.posts_id
group by tp.oid having create_time = max(create_time)

假設(shè)現(xiàn)在有兩個文章A, B (回復的記錄在數(shù)據(jù)庫的順序與下述一致)

A有一個回復記錄時間為: 2019-09-10  
A有一個回復記錄時間為: 2019-09-11  
B有一個回復記錄時間為: 2019-09-01  
B有一個回復記錄時間為: 2019-09-09

運行上面的sql, 會發(fā)現(xiàn)結(jié)果集丟失大量記錄, 并且結(jié)果是錯誤的, 經(jīng)過查詢資料得知

mysql的 having 是在 group by 之后再執(zhí)行, 也就是說, 先分組, 在過濾, 但是因為存在兩條以上的留言記錄,
所以分組之后的結(jié)果集只會取每條留言的第一條作為分組之后的記錄信息, 這時如果使用having create_time = max(create_time)
那么, max(create_time) 為當前分組的最大時間

為: 2019-09-10 和 2019-09-09

所以上述sql會丟失結(jié)果集

4.改造SQL

因為知道分組之后合并的重復結(jié)果集為rownum最小的那條, 那么可不可以改造sql如下??

select 
  tp.oid,
  tp.posts_name,
  tc.msg_content,
  tc.create_time
from t_posts tp 
left join t_comment tc on tp.oid = tc.posts_id
group by tp.oid having create_time = max(create_time)
-- 下面的是新增的sql
order by tc.create_time desc

運行之后發(fā)現(xiàn)依舊不好使, 證明order by 在group by & having 之后

后來想想可不可以 不用having, 直接用order by來優(yōu)化分組后的結(jié)果呢?

having create_time = max(create_time)

select 
  tp.oid,
  tp.posts_name,
  tc.msg_content,
  tc.create_time
from t_posts tp 
left join t_comment tc on tp.oid = tc.posts_id
group by tp.oid 
order by tc.create_time desc

結(jié)果集錯誤, 并不能影響分組結(jié)果, 依舊是按照rownum最小分組合并重復結(jié)果集, 然后在排序

5.終極改造版本

因為order by 只能后影響group by, 那么是不是可以在group by 之前先把結(jié)果集排序一下, 然后再分組呢?

select * from (
  select 
    tp.oid,
    tp.posts_name,
    tc.msg_content,
    tc.create_time
  from t_posts tp 
  left join t_comment tc on tp.oid = tc.posts_id
  order by tc.create_time desc
) t 
group by t.oid

發(fā)現(xiàn)還是不好使, 但是子查詢確實先排序了

經(jīng)查詢(explain), 發(fā)現(xiàn)子查詢的order by被優(yōu)化沒了, 解決辦法:

  1. 在子查詢里使用limit 99999

  2. 在子查詢里使用where條件, create_time = (select max(create_time) from t_comment group by oid)

select * from (
  select 
    tp.oid,
    tp.posts_name,
    tc.msg_content,
    tc.create_time
  from t_posts tp 
  left join t_comment tc on tp.oid = tc.posts_id
  order by tc.create_time desc limit 9999
) t 
group by t.oid

大功告成

附加知識點:

mysql5.5 與 mysql 5.7 版本差異: 5.7+ 版本, 如果不使用 limit, group by 會把 order by 優(yōu)化掉

關(guān)于“MySql Group by函數(shù)怎么正確使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“MySql Group by函數(shù)怎么正確使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

當前文章:MySqlGroupby函數(shù)怎么正確使用
網(wǎng)頁鏈接:http://bm7419.com/article30/gighso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、全網(wǎng)營銷推廣、商城網(wǎng)站、網(wǎng)站內(nèi)鏈建站公司、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計