国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

MySql Group by函數(shù)怎么正確利用

2024-07-24 12:33:32
字體:
供稿:網(wǎng)友

  這篇文章主要介紹了MySql Group by函數(shù)怎么正確使用的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇MySql Group by函數(shù)怎么正確使用文章都會有所收獲,下面我們一起來看看吧。
 
  MySql Group by 函數(shù)的正確打開方式
  在使用分組函數(shù)時, 進(jìn)行結(jié)果集篩選, 遇到的一些問題以及解決辦法
 
  1. 應(yīng)用場景
 
  有兩張表
 
  文章表(一對多留言表) t_posts:      
  oid, posts_name    
  留言表(多對一文章表) t_comment:    
  oid, posts_id, msg_content, create_time
 
  2.需求分析
 
  查詢每個文章的最新回復(fù)內(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 (回復(fù)的記錄在數(shù)據(jù)庫的順序與下述一致)
 
  A有一個回復(fù)記錄時間為: 2019-09-10   
  A有一個回復(fù)記錄時間為: 2019-09-11   
  B有一個回復(fù)記錄時間為: 2019-09-01   
  B有一個回復(fù)記錄時間為: 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) 為當(dāng)前分組的最大時間
 
  為: 2019-09-10 和 2019-09-09
 
  所以上述sql會丟失結(jié)果集
 
  4.改造SQL
 
  因為知道分組之后合并的重復(fù)結(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最小分組合并重復(fù)結(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)化沒了, 解決辦法:
 
  在子查詢里使用limit 99999
  在子查詢里使用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)容就介紹到這里,感謝各位的閱讀!

(編輯:武林網(wǎng))

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 辉南县| 池州市| 玉门市| 县级市| 丽水市| 尚义县| 衡阳县| 巧家县| 和平县| 海城市| 静乐县| 江达县| 湖口县| 西峡县| 永德县| 青岛市| 洞口县| 洛隆县| 汉阴县| 社旗县| 大厂| 贵州省| 广昌县| 中宁县| 贡山| 岗巴县| 康定县| 通山县| 祁门县| 肥城市| 德江县| 武鸣县| 靖安县| 遂溪县| 合肥市| 淳化县| 台中市| 濉溪县| 巴彦县| 屯昌县| 鸡泽县|