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

MySQL GROUP_CONCAT 實戰:多行聚合為單字串、自定義分隔符與長度限制

     編輯:MySQL 資料庫相關知識

場景

一對多關聯查詢需「一行顯示所有關聯值」:班級-學生、訂單-商品、用戶-標籤、文章-分類。

基礎語法


GROUP_CONCAT([DISTINCT] expr [ORDER BY ...] [SEPARATOR str])
-- 返回聚合後字串,預設分隔符 ','
-- NULL 值自動忽略

實戰範例


-- 表結構
CREATE TABLE banji (id INT PRIMARY KEY, class_name VARCHAR(20));
CREATE TABLE user (id INT PRIMARY KEY, name VARCHAR(20), class_id INT);

-- 需求:查班級及所有學生名單
SELECT b.id, b.class_name, GROUP_CONCAT(u.name) AS names
FROM banji b
LEFT JOIN user u ON b.id = u.class_id
WHERE b.id = 2
GROUP BY b.id, b.class_name;

-- 結果
id  class_name  names
2   二班        lisi,zhaoliu,liu,小二,xiaoming,小張

進階用法

自定義分隔符


GROUP_CONCAT(u.name SEPARATOR '|')
-- lisi|zhaoliu|liu|小二|xiaoming|小張

去重 + 排序


GROUP_CONCAT(DISTINCT u.name ORDER BY u.name SEPARATOR ',')

限制長度(防止截斷)

  • 系統變數 group_concat_max_len 預設 1024 字節,超長截斷
  • 會話級調大:SET SESSION group_concat_max_len = 1000000;
  • 全域永久:my.cnf group_concat_max_len = 1000000

應用層拆分


-- PHP
$names = explode(',', $row['names']);
-- Python
names = row['names'].split(',')
-- Java
String[] names = row.get("names").split(",");

效能與避坑

  • 大量聚合:單組超過 group_concat_max_len 靜默截斷,必須調大
  • 記憶體:臨時表構建結果集,超大聚合可能導致 Created_tmp_disk_tables 增加
  • 替代方案:應用層分批查詢 + 組裝,或用 JSON_ARRAYAGG (5.7+) 返回結構化陣列

JSON_ARRAYAGG 現代替代 (MySQL 5.7+)


SELECT b.id, b.class_name, JSON_ARRAYAGG(u.name) AS names
FROM banji b
LEFT JOIN user u ON b.id = u.class_id
GROUP BY b.id, b.class_name;
-- 返回 ["lisi","zhaoliu","liu","小二","xiaoming","小張"]
-- 應用層直接 JSON.parse,無分隔符煩惱,支援嵌套結構

小結

GROUP_CONCAT 是一對多「扁平化」顯示的利器:SEPARATOR 自定義分隔、DISTINCT 去重、ORDER BY 排序。注意 group_concat_max_len 截斷陷阱。5.7+ 推薦 JSON_ARRAYAGG 返回標準 JSON 陣列,應用層處理更優雅。

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