一對多關聯查詢需「一行顯示所有關聯值」:班級-學生、訂單-商品、用戶-標籤、文章-分類。
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 增加
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 陣列,應用層處理更優雅。