首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL GROUP_CONCAT 函數完全指南:語法、分組邏輯、長度限制與實戰場景

     編輯:MySQL 資料庫相關知識

函數定義

返回結果集中每組非 NULL 值的連接字符串。需配合 GROUP BY 使用,否則整個結果集視為一組。

完整語法

GROUP_CONCAT(
    [DISTINCT] expr
    [ORDER BY {unsigned_integer | col_name | expr} [ASC|DESC] [, ...]]
    [SEPARATOR str_val]
)

核心參數詳解

子句作用默認值示例
DISTINCT去除重複值不去重GROUP_CONCAT(DISTINCT city)
ORDER BY組內排序無序 (依存儲順序)GROUP_CONCAT(name ORDER BY id DESC)
SEPARATOR分隔符',' (逗號)GROUP_CONCAT(tag SEPARATOR '|')

分組邏輯驗證實驗

CREATE TABLE players (id INT, name VARCHAR(20), town VARCHAR(20));
INSERT INTO players VALUES 
(1,'Alice','北京'),(2,'Bob','長沙'),(3,'Cindy','北京');

-- 1. 無 GROUP BY:整表一組
SELECT GROUP_CONCAT(town) FROM players;
-- 結果: 北京,長沙,北京

-- 2. GROUP BY town:按城市分組
SELECT GROUP_CONCAT(name) FROM players GROUP BY town;
-- 結果: 
-- town=北京: Alice,Cindy
-- town=長沙: Bob

-- 3. 多列 GROUP_CONCAT
SELECT GROUP_CONCAT(name, ':', town) FROM players GROUP BY town;
-- 結果: Alice:北京,Cindy:北京 / Bob:長沙

關鍵限制:group_concat_max_len

-- 查看默認 (1024 字節)
SHOW VARIABLES LIKE 'group_concat_max_len';

-- 會話級調大
SET SESSION group_concat_max_len = 1024000;  -- 1MB

-- 全局永久 (my.cnf)
[mysqld]
group_concat_max_len = 1024000

-- 超長行為:截斷 + Warning (Code 1260)
SHOW WARNINGS;
-- | Warning | 1260 | 1 line(s) were cut by GROUP_CONCAT() |

實戰場景與優化

場景一:標籤聚合 (文章-標籤多對多)

SELECT 
    a.id, a.title,
    GROUP_CONCAT(t.name ORDER BY t.id SEPARATOR ',') AS tags
FROM article a
LEFT JOIN article_tag at ON a.id = at.article_id
LEFT JOIN tag t ON at.tag_id = t.id
GROUP BY a.id, a.title;

場景二:報表導出 (部門-員工明細)

SELECT 
    d.name AS dept,
    GROUP_CONCAT(CONCAT(e.name,'(',e.emp_no,')') ORDER BY e.hire_date SEPARATOR '; ') AS employees
FROM dept d
LEFT JOIN emp e ON d.id = e.dept_id
GROUP BY d.id, d.name;

場景三:條件聚合 (只聚合啟用狀態)

SELECT 
    user_id,
    GROUP_CONCAT(CASE WHEN status=1 THEN role_name END ORDER BY role_id SEPARATOR ',') AS active_roles
FROM user_role
GROUP BY user_id;

性能優化建議

優化點說明
索引支撐 GROUP BY確保 GROUP BY 列有索引,避免臨時表+文件排序
避免 DISTINCTDISTINCT 需額外排序/哈希去重,業務允許則不加
控制結果集大小單行超長影響網絡傳輸、內存,必要時 SUBSTRING_INDEX 截取前 N 個
大數據量分頁應用層分頁查詢,每頁 GROUP_CONCAT,而非全量聚合

跨數據庫對比

數據庫對應函數語法差異
MySQLGROUP_CONCATSEPARATOR、ORDER BY 靈活
PostgreSQLSTRING_AGGSTRING_AGG(expr, delimiter) ORDER BY ...
OracleLISTAGGLISTAGG(expr, delimiter) WITHIN GROUP (ORDER BY ...)
SQL ServerSTRING_AGG (2017+)STRING_AGG(expr, delimiter) [WITHIN GROUP (ORDER BY ...)]
SQLiteGROUP_CONCAT語法與 MySQL 幾乎相同

避坑清單

  1. 忘記 GROUP BY:全表聚合成一行,非預期
  2. NULL 值被忽略:GROUP_CONCAT 自動跳過 NULL,如需保留用 IFNULL(expr,'NULL')
  3. 超長截斷無報錯:只產生 Warning,應用層需檢查長度或調大參數
  4. SEPARATOR 含特殊字符:如 ',' 在 CSV 中衝突,建議用 '|' 或 '\t'
  5. 字符集不一致:表/連接/結果字符集不一致導致亂碼,統一 utf8mb4

GROUP_CONCAT 是 MySQL 最實用的聚合函數之一,**掌握「分組+排序+分隔符+長度控制」四要素**,能優雅解決「一對多扁平化輸出」90% 的場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved