mysql中的group?by用法指南
MySQL中的GROUP BY
是數(shù)據(jù)聚合分析的核心功能,主要用于將結(jié)果集按指定列分組,并結(jié)合聚合函數(shù)進行統(tǒng)計計算。以下從基本語法到高級用法進行詳細解析:
一、基本語法與核心功能
SELECT 分組列, 聚合函數(shù)(計算列) FROM 表名 [WHERE 條件] GROUP BY 分組列 [HAVING 分組過濾條件] [ORDER BY 排序列];
核心功能:
- 數(shù)據(jù)分組:按一列或多列的值將數(shù)據(jù)劃分為邏輯組。
- 聚合計算:對每個分組應用聚合函數(shù)(如
COUNT
、SUM
、AVG
、MAX
、MIN
)進行統(tǒng)計。 - 結(jié)果過濾:通過
HAVING
對分組后的結(jié)果進行篩選(區(qū)別于WHERE
的分組前過濾)。
二、基礎用法示例
1. 單列分組統(tǒng)計
統(tǒng)計每個部門的員工數(shù)量和平均工資:
SELECT department, COUNT(*) AS emp_count, AVG(salary) AS avg_salary FROM employees GROUP BY department; --
2. 多列組合分組
按部門和職位統(tǒng)計員工數(shù)量:
SELECT department, job_title, COUNT(*) FROM employees GROUP BY department, job_title; --
3. 與WHERE結(jié)合使用
僅統(tǒng)計薪資超過2000元的員工部門平均工資:
SELECT department, AVG(salary) FROM employees WHERE salary > 2000 GROUP BY department; --
三、高級特性與擴展
1. HAVING子句過濾分組
篩選員工數(shù)量超過5人的部門:
SELECT department, COUNT(*) AS emp_count FROM employees GROUP BY department HAVING emp_count > 5; --
2. WITH ROLLUP生成匯總行
生成部門及職位的薪資小計和總計:
SELECT department, job_title, SUM(salary) FROM employees GROUP BY department, job_title WITH ROLLUP; --
3. GROUP_CONCAT合并列值
統(tǒng)計每個用戶購買的所有產(chǎn)品(逗號分隔):
SELECT user_id, GROUP_CONCAT(product_name SEPARATOR ', ') FROM orders GROUP BY user_id; --
4. 按表達式/函數(shù)分組
按年份統(tǒng)計訂單數(shù)量:
SELECT YEAR(order_date) AS year, COUNT(*) FROM orders GROUP BY YEAR(order_date); --
四、注意事項與常見錯誤
ONLY_FULL_GROUP_BY模式
MySQL 8.0+默認啟用該模式,要求SELECT
中的非聚合列必須出現(xiàn)在GROUP BY
中,否則報錯。
-- 錯誤示例(salary未聚合且未分組) SELECT department, salary FROM employees GROUP BY department; -- 修正方法:添加聚合函數(shù)或分組字段 SELECT department, MAX(salary) FROM employees GROUP BY department;
WHERE與HAVING的區(qū)別
WHERE
在分組前過濾行數(shù)據(jù),不可使用聚合函數(shù)。HAVING
在分組后過濾組數(shù)據(jù),必須與聚合條件結(jié)合。
性能優(yōu)化建議
- 在分組列上創(chuàng)建索引(如
ALTER TABLE employees ADD INDEX(department)
)。 - 避免對大表直接分組,可先通過臨時表或子查詢縮小數(shù)據(jù)范圍。
五、經(jīng)典案例場景
1. 按時間維度聚合
統(tǒng)計每月的銷售總額:
SELECT YEAR(sale_date) AS year, MONTH(sale_date) AS month, SUM(amount) FROM sales GROUP BY year, month; --
2. 多層級統(tǒng)計
分析每個客戶每年的訂單總金額及平均金額:
SELECT customer_id, YEAR(order_date), SUM(total_amount), AVG(total_amount) FROM orders GROUP BY customer_id, YEAR(order_date); --
3. 數(shù)據(jù)去重
查找重復郵箱的用戶:
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1; --
六、聚合效率優(yōu)化
在MySQL中優(yōu)化GROUP BY
聚合效率需要從索引設計、查詢邏輯、執(zhí)行引擎特性等多維度入手。以下基于最新優(yōu)化實踐和數(shù)據(jù)庫引擎特性,總結(jié)9大核心優(yōu)化策略:
1、索引優(yōu)化策略
復合索引精準匹配分組列
• 創(chuàng)建與GROUP BY
順序完全匹配的復合索引(如GROUP BY a,b
則創(chuàng)建(a,b)
索引),可觸發(fā)松散索引掃描,減少90%以上的磁盤I/O。
• 典型案例:當對(department, job_title)
分組時,復合索引idx_dept_job
可使查詢跳過全表掃描,直接通過索引完成分組。
覆蓋索引避免回表
• 確保SELECT
列與聚合函數(shù)涉及的列均包含在索引中。例如索引(category, sales)
,查詢SELECT category, SUM(sales)
時可直接通過索引完成計算,無需訪問數(shù)據(jù)行。
利用函數(shù)索引應對復雜分組
• 對含表達式的分組(如YEAR(date_col)
),創(chuàng)建虛擬列或函數(shù)索引(MySQL 8.0+支持)。例如:
ALTER TABLE orders ADD COLUMN year_date INT AS (YEAR(order_date)) VIRTUAL; CREATE INDEX idx_year ON orders(year_date);
2、查詢設計與執(zhí)行優(yōu)化
減少分組字段數(shù)量與復雜度
• 每增加一個分組字段,排序復雜度呈指數(shù)級增長。優(yōu)先合并相關字段(如將province
和city
合并為region
字段)。
• 避免在GROUP BY
中使用函數(shù),否則索引失效。需改寫為基于原字段分組,如將GROUP BY DATE(created_at)
改為GROUP BY created_at_date
預計算列。
分階段過濾與聚合
• 先通過子查詢過濾無關數(shù)據(jù)再分組:
SELECT department, AVG(salary) FROM (SELECT * FROM employees WHERE salary > 5000) AS filtered GROUP BY department; -- 比直接HAVING效率提升40%
內(nèi)存排序與臨時表優(yōu)化
• 調(diào)整tmp_table_size
和max_heap_table_size
參數(shù)(建議設置為物理內(nèi)存的20%),避免臨時表落盤。
• 監(jiān)控Created_tmp_disk_tables
狀態(tài)變量,若頻繁出現(xiàn)磁盤臨時表,需優(yōu)化索引或拆分查詢。
3、高級優(yōu)化技術
分區(qū)表加速大數(shù)據(jù)處理
• 按時間或業(yè)務維度分區(qū)(如按月分區(qū)),使GROUP BY
僅掃描特定分區(qū)。例如對10億級日志表按event_date
分區(qū)后,月度統(tǒng)計耗時從分鐘級降至秒級。
物化視圖與結(jié)果緩存
• 對高頻聚合查詢使用物化視圖(如通過CREATE TABLE mv AS SELECT...
定期刷新),減少實時計算壓力。
• 應用層緩存重復查詢結(jié)果(如Redis緩存日匯總數(shù)據(jù)),降低數(shù)據(jù)庫負載。
并行查詢(MySQL 8.0+)
• 啟用parallel_query
功能,通過多線程處理復雜分組:
SET SESSION optimizer_switch='parallel_query=on'; SELECT region, SUM(revenue) FROM sales GROUP BY region; -- 利用多核CPU加速
4、診斷工具與注意事項
• 執(zhí)行計劃分析
使用EXPLAIN FORMAT=JSON
觀察using_index
(是否用索引)、using_temporary
(是否用臨時表)、filesort
(排序方式)等關鍵指標。
• 嚴格模式規(guī)避錯誤
啟用ONLY_FULL_GROUP_BY
模式,防止非聚合列誤用導致結(jié)果不穩(wěn)定。
性能優(yōu)化對比案例
場景 | 優(yōu)化前耗時 | 優(yōu)化手段 | 優(yōu)化后耗時 |
---|---|---|---|
百萬級用戶行為分析 | 12.8s | 創(chuàng)建(user_id,action_time) 覆蓋索引 | 1.2s |
十億級日志日聚合 | 3分鐘 | 按日分區(qū)+并行查詢 | 8秒 |
通過上述策略組合,可系統(tǒng)性解決GROUP BY
性能瓶頸。實際應用中建議結(jié)合EXPLAIN
分析和A/B測試,選擇最適合業(yè)務場景的優(yōu)化方案。
七、擴展知識
- NULL值的處理:
GROUP BY
將NULL
視為獨立分組。 - 排序結(jié)合:分組后使用
ORDER BY
對結(jié)果排序(如按平均工資降序)。 - 動態(tài)分組:通過
CASE WHEN
實現(xiàn)條件分組(如按薪資區(qū)間統(tǒng)計)。
通過靈活組合這些功能,GROUP BY
可滿足復雜的數(shù)據(jù)分析需求。實際應用中需結(jié)合索引優(yōu)化和查詢邏輯設計,以提升執(zhí)行效率。
到此這篇關于mysql中的group by用法詳解的文章就介紹到這了,更多相關mysql group by用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- mysql的group by函數(shù)使用方法
- MySQL的GROUP BY與COUNT()函數(shù)的使用方法及常見問題
- mysql中的group?by和between用法詳解
- mysql中的group by高級用法
- MySQL GROUP BY分組取字段最大值的方法示例
- MySQL中distinct和group by去重的區(qū)別解析
- MySQL中ONLY_FULL_GROUP_BY的使用小結(jié)
- MySQL 5.7升級8.0報異常:ONLY_FULL_GROUP_BY的問題解決
- 解決mysql @@sql_mode問題---only_full_group_by
- mysql group by 多個行轉(zhuǎn)換為一個字段
相關文章
結(jié)合PHP腳本添加和查詢MySQL數(shù)據(jù)的基本教程
這篇文章主要介紹了結(jié)合PHP腳本添加和查詢MySQL數(shù)據(jù)的基本教程,即在PHP程序中使用基本的SELECT FROM和INSERT INTO語句,需要的朋友可以參考下2015-12-12mysql忘記root密碼的解決辦法(針對不同mysql版本)
這篇文章主要介紹了mysql忘記root密碼的解決辦法(針對不同mysql版本),文章通過代碼示例和圖文結(jié)合的方式給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-06-06MySQL數(shù)據(jù)庫中Interval關鍵字的使用看這一篇就夠了
這篇文章主要給大家介紹了關于MySQL數(shù)據(jù)庫中Interval關鍵字使用的相關資料,interval作為一個關鍵字時,表示為時間間隔,常用在date_add()、date_sub()、subdate(),函數(shù)中,常用于時間的加減法,需要的朋友可以參考下2024-08-08mysql group by 多個行轉(zhuǎn)換為一個字段
本文主要介紹了mysql group by 多個行轉(zhuǎn)換為一個字段,可以使用聚合函數(shù)GROUP_CONCAT()函數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-08-08sql語句escape查詢數(shù)據(jù)中含通配字符[ %用法詳解
這篇文章主要為大家介紹了sql語句escape查詢數(shù)據(jù)中含通配字符[ %用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08MySQL gh-ost DDL 變更工具的實現(xiàn)
本文主要介紹了MySQL gh-ost DDL變更工具的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-02-02使用mysqldump如何實現(xiàn)數(shù)據(jù)庫表備份
這篇文章主要介紹了使用mysqldump如何實現(xiàn)數(shù)據(jù)庫表備份方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2013-06-06MySQL之七種SQL JOINS實現(xiàn)的圖文詳解
這篇文章主要介紹了MySQL中七種SQL JOINS的實現(xiàn)方法及圖文詳解,文中也有相關的代碼示例供大家參考,感興趣的同學可以參考閱讀下2023-06-06