GROUP_CONCAT 是 MySQL 聚合查詢的利器,能將分組內的多行值合併為單一字串,極大簡化了報表統計、標籤聚合等場景的開發。本文系統梳理語法細節、長度限制突破、實戰案例與避坑指南。
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {col_name | expr} [ASC | DESC]]
[SEPARATOR str_val])
簡記版:GROUP_CONCAT([DISTINCT] 欄位 [ORDER BY 排序] [SEPARATOR '分隔符'])
預設 group_concat_max_len=1024,超長字串會被截斷。兩種調整方式:
SET SESSION group_concat_max_len=10240;(推薦,不影響其他連線)SET GLOBAL group_concat_max_len=10240; 或 my.cnf 加入 group_concat_max_len=10240測試表 aa(id, name) 數據:
id | name
1 | 10
1 | 20
1 | 20
2 | 20
3 | 200
3 | 500
SELECT id, GROUP_CONCAT(name) FROM aa GROUP BY id;
-- 1 | 10,20,20
-- 2 | 20
-- 3 | 200,500
SELECT id, GROUP_CONCAT(name SEPARATOR ';') FROM aa GROUP BY id;
-- 1 | 10;20;20
SELECT id, GROUP_CONCAT(DISTINCT name) FROM aa GROUP BY id;
-- 1 | 10,20
SELECT id, GROUP_CONCAT(name ORDER BY name DESC) FROM aa GROUP BY id;
-- 1 | 20,20,10
景點-類型多對多關聯,需將類型名稱聚合:
SELECT s.id, s.name,
GROUP_CONCAT(stt.name SEPARATOR ',') AS TypeName
FROM scenics s
INNER JOIN scenics_type srt ON srt.scenicsId = s.id
INNER JOIN scenicstype stt ON stt.id = srt.typeId AND stt.deleted=0
GROUP BY s.id;
單條 SQL 替代應用層循環查詢,效能提升數量級。
GROUP_CONCAT(int欄位) 返回二進制字節流而非字串,必須顯式轉型:
-- 錯誤:返回 byte[]
SELECT GROUP_CONCAT(id) FROM t_ip;
-- 正確:CAST 或 CONVERT
SELECT GROUP_CONCAT(CAST(id AS CHAR)) FROM t_dep;
SELECT GROUP_CONCAT(CONVERT(id, CHAR)) FROM t_dep;
即使調大 group_concat_max_len,極端數據仍可能超限。建議:
SHOW STATUS LIKE 'Group_concat%'; 觀察實際截斷情況GROUP_CONCAT(*)WHERE 縮小掃描範圍MAX(length) 預檢查結果長度善用 GROUP_CONCAT 能讓複雜聚合查詢化繁為簡,但必須敬畏其長度限制與類型轉換陷阱,才能在生產環境穩健落地。