前兩天同事有個 MySQL 數(shù)據(jù)分組的需求,如下測試數(shù)據(jù),需要找出每個 name 分組中 create_date 最近的記錄:
成都創(chuàng)新互聯(lián)長期為上1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為黑山企業(yè)提供專業(yè)的網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè),黑山網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
需要注意的是,此處用的 MySQL 是5.6,最初是使用這條語句:
pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;" select name, value, create_date, update_date from t1 group by name order by create_date desc; /pre
用這條 SQL 得到的其實只是每個 name 分組中最先插入的記錄,然后按照 create_date 進行了降序排列,和原始需求,完全不同。
此時可采用分而治之的策略,先做排序,再做分組:
pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;" select * from (select name, value, create_date, update_date from t1 order by create_date desc) t group by t.name; /pre
當(dāng)然,針對此需求,可能有其他方法,有興趣的朋友,可以嘗試寫寫,共享一下。
可能有細(xì)心的朋友會發(fā)現(xiàn)個問題,就是上述 SQL 中的 group by ,好像有些奇怪,如果按照常規(guī),select 中的字段需要出現(xiàn)在 group by 中,上述語句竟然沒報錯?
如果我們在 MySQL 5.7 執(zhí)行相同的語句:
pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;" select name, value, create_date, update_date from t1 group by name order by create_date desc; /pre
因此從5.6升級到5.7,很可能出現(xiàn)這種相同的 SQL 執(zhí)行結(jié)果不同的現(xiàn)象,這對兼容性測試的要求就會很高,究其原因,一方面是特性決定的,另一方面就是各種配置參數(shù)不同導(dǎo)致的。
可以在5.7的 sql_mode 中刪除這個 ONLY_FULL_GROUP_BY ,即可達(dá)到5.6相同效果了,或者改寫 SQL ,例如:
pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;" select * from t1 a where create_date = (select max(create_date) from t1 b where a.name = b.name); /pre
或者,
pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;" select * from t1 a where not exists (select * from t1 b where a.name = b.name and b.create_date a.create_date); /pre
MySQL 8.0支持 row_number()函數(shù),操作應(yīng)該和如下 Oracle 相近的。
Oracle 中可以使用 row_number()實現(xiàn)此需求:
pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;" select * from (select name, create_date, row_number() over (partition by name order by create_date desc) as r from t1) where r=1; /pre
上一篇聚合函數(shù)末尾處使用了GROUP BY,但沒有做具體的介紹,這一篇就主要介紹一下GROUP BY的使用方法。順便介紹一下對分組查詢的過濾關(guān)鍵詞HAVING的用法。
在MySQL中,GROUP BY關(guān)鍵詞可以根據(jù)一個或多個字段對查詢結(jié)果進行分組,類似于Excel中的數(shù)據(jù)透視表??梢詥为毷褂茫话闱闆r下都是結(jié)合聚合函數(shù)來使用的。
語法格式如下:
下面演示都是基于這一張簡單的省份對應(yīng)大區(qū)的表格。
【單獨使用GROUP BY】
單獨使用GROUP BY關(guān)鍵字時,查詢結(jié)果會只顯示每個分組的第一條記錄。
根據(jù)省份表里面的大區(qū)進行聚合,查詢?nèi)珖卜殖闪藥讉€大區(qū),SQL語句如下↓
【GROUP BY結(jié)合聚合函數(shù)】
5個聚合函數(shù)上一篇已經(jīng)詳細(xì)介紹了用法,GROUP BY和聚合函數(shù)結(jié)合使用也是最頻繁的,下面就繼續(xù)使用省份表來求每個大區(qū)有多少個省份,對應(yīng)的聚合函數(shù)就是COUNT函數(shù),SQL語句如下↓
【GROUP BY結(jié)合GROUP_CONCAT】
這還是一個很有用的功能,GROUP_CONCAT() 函數(shù)會把每個分組的字段值都合并成一行顯示出來。
下面繼續(xù)使用省份表,把每個大區(qū)對應(yīng)的省份放在一行展示,用分號分開,SQL語句如下↓
【GROUP BY結(jié)合WITH ROLLUP】
WITH POLLUP關(guān)鍵詞用來在所有記錄的最后加上一條記錄,這條記錄是上面所有記錄的總和,SQL語句如下↓
【GROUP BY結(jié)合HAVING】
在MySQL中,可以使用HAVING關(guān)鍵字對分組后的數(shù)據(jù)進行過濾。
使用 HAVING 關(guān)鍵字的語法格式如下:
HAVING關(guān)鍵詞和WHERE關(guān)鍵詞都可以用來過濾數(shù)據(jù),且HAVING支持WHERE關(guān)鍵詞中所有的操作符和語法。但是WHERE和HAVING關(guān)鍵字也存在以下幾點差異:
下面篩選一下省份數(shù)量在7個及以上的大區(qū),SQL語句如下↓
【GROUP BY結(jié)合ORDER BY】
聚合后的數(shù)據(jù),一半情況下也是需要進行排序的,通過ORDER BY對聚合查詢結(jié)果進行排序,對省份數(shù)量按從大到小進行排序,SQL語句如下↓
End
◆ PowerBI開場白
◆ Python高德地圖可視化
◆ Python不規(guī)則條形圖
MySQL GROUP BY 子句
GROUP BY 語句根據(jù)一個或多個列對結(jié)果集進行分組。在分組的列上我們可以使用 COUNT, SUM, AVG,等函數(shù)。
具體語法參考:
from 樹懶學(xué)堂 - 一站式數(shù)據(jù)知識平臺
新聞標(biāo)題:mysql中分組怎么寫,mysql中分組函數(shù)怎么寫
本文鏈接:http://chinadenli.net/article10/hscego.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗、商城網(wǎng)站、做網(wǎng)站、網(wǎng)站設(shè)計公司、網(wǎng)站排名、服務(wù)器托管
聲明:本網(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)