GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
DISTINCT:去除重複值ORDER BY:組內排序後再拼接SEPARATOR:自定義分隔符,預設為逗號 ,-- 學生 2 選修課程合併為一行
SELECT student_id, GROUP_CONCAT(courses_id) AS courses
FROM student_courses
WHERE student_id = 2
GROUP BY student_id;
-- 結果: 2 | 3,4,5
PHP 端只需 explode(',', $row['courses']) 即可得到數組,省去 foreach 迭代。
SELECT student_id, GROUP_CONCAT(courses_id SEPARATOR '|||') AS courses
FROM student_courses
WHERE student_id = 2
GROUP BY student_id;
-- 結果: 2 | 3|||4|||5
當字段本身包含逗號時,改用 ||| 等特殊符號更安全。
SELECT student_id, GROUP_CONCAT(courses_id ORDER BY courses_id DESC) AS courses
FROM student_courses
WHERE student_id = 2
GROUP BY student_id;
-- 結果: 2 | 5,4,3
現象:GROUP_CONCAT(id) 在程式語言驅動中返回 byte[],而 SQLyog 等工具顯示正常字符串,極易誤判。
根因:數值類型拼接時未隱式轉字符集。
修正:強制轉型為 CHAR:
SELECT GROUP_CONCAT(CAST(id AS CHAR)) FROM t_dep;
SELECT GROUP_CONCAT(CONVERT(id, CHAR)) FROM t_dep;
預設限制:1024 字節(1KB),超長直接截斷,不報錯。
查看當前值:
SHOW VARIABLES LIKE 'group_concat_max_len';
修改方式:
SET SESSION group_concat_max_len = 102400;SET GLOBAL group_concat_max_len = 102400; 或在 my.cnf 增加 group_concat_max_len = 102400注意:LIMIT 子句無法限制 GROUP_CONCAT 的輸出長度,只能調大該變數。
CREATE TABLE student_courses (
student_id INT UNSIGNED NOT NULL,
courses_id INT UNSIGNED NOT NULL,
KEY(student_id)
);
INSERT INTO student_courses VALUES (1,1),(1,2),(2,3),(2,4),(2,5);
| 目標類型 | 說明 |
|---|---|
| BINARY[(N)] | 二進制字符串 |
| CHAR[(N)] | 定長字符串 |
| DATE / DATETIME / TIME | 日期時間類型 |
| DECIMAL / SIGNED / UNSIGNED | 數值類型 |
GROUP_CONCAT 是將多行聚合為單字符串的利器,善用 SEPARATOR、ORDER BY 可大幅簡化應用層代碼。但務必記住:數值字段必須 CAST 為 CHAR,且根據業務量級 適度調大 group_concat_max_len,才能避免「明明查到了卻只拿到一半」的詭異 Bug。