GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
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);
SELECT student_id, courses_id FROM student_courses WHERE student_id = 2;
/* 結果:
student_id | courses_id
2 | 3
2 | 4
2 | 5
*/
PHP 處理需迴圈:
$result = [];
foreach ($pdo->query("SELECT student_id, courses_id FROM student_courses WHERE student_id=2") as $row) {
$result[] = $row['courses_id'];
}
// $result = [3, 4, 5]
SELECT student_id, GROUP_CONCAT(courses_id) AS courses
FROM student_courses
WHERE student_id = 2
GROUP BY student_id;
/* 結果:
student_id | courses
2 | 3,4,5
*/
PHP 處理變簡單:
$row = $pdo->query("SELECT student_id, GROUP_CONCAT(courses_id) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id")->fetch();
$result = explode(',', $row['courses']);
// $result = [3, 4, 5]
SELECT student_id, GROUP_CONCAT(courses_id SEPARATOR '|||') AS courses
FROM student_courses
WHERE student_id = 2
GROUP BY student_id;
/* 結果:3|||4|||5 */
-- 依課程 ID 降序
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;
/* 結果:5,4,3 */
SELECT student_id, GROUP_CONCAT(DISTINCT courses_id) AS courses
FROM student_courses
GROUP BY student_id;
SELECT student_id,
GROUP_CONCAT(CONCAT(course_name, ':', score) ORDER BY score DESC SEPARATOR '; ') AS course_scores
FROM student_courses sc
JOIN courses c ON sc.courses_id = c.id
GROUP BY student_id;
預設長度限制: 1024 位元組,超截會被截斷。
-- 暫時調大(當前連線有效)
SET SESSION group_concat_max_len = 10000;
-- 永久調整(my.cnf/my.ini)
[mysqld]
group_concat_max_len = 10000
group_concat_max_len 與記憶體使用GROUP BY 欄位應建立索引| 場景 | 傳統做法 | GROUP_CONCAT 優勢 |
|---|---|---|
| 標籤系統 | 多次查詢或 JOIN 產生重複主記錄 | 單查詢獲取逗點分隔標籤字串 |
| 分類路徑 | 遞迴查詢或應用層組裝 | SQL 直接產生「父>子>孫」路徑 |
| 報表匯出 | 應用層迴圈組字串 | 資料庫層完成,減少網路傳輸 |