一、函数定义与基础语法
GROUP_CONCAT(
[DISTINCT] 字段名
[ORDER BY 排序字段 [ASC|DESC]]
[SEPARATOR '分隔符']
)
默认行为:连接非NULL值,默认逗号分隔
长度限制:受group_concat_max_len控制(默认1024字节)
二、核心使用场景与示例
1. 基础字符串连接
-- 连接部门所有员工姓名
SELECT
dept_id,
GROUP_CONCAT(employee_name) AS members
FROM employees
GROUP BY dept_id;
输出示例:
| dept_id | members |
|---------|------------------|
| 1 | 张三,李四,王五 |
2. 去重连接(DISTINCT)
-- 连接不重复的城市名
SELECT
country,
GROUP_CONCAT(DISTINCT city) AS cities
FROM locations
GROUP BY country;
3. 自定义排序(ORDER BY)
-- 按入职时间倒序连接
SELECT
dept_id,
GROUP_CONCAT(
employee_name
ORDER BY hire_date DESC
SEPARATOR ' | '
) AS seniority_list
FROM employees
GROUP BY dept_id;
4. 多字段组合
-- 连接姓名+工号
SELECT
project_id,
GROUP_CONCAT(
CONCAT(name,'(',emp_id,')')
SEPARATOR '; '
) AS project_team
FROM project_members
GROUP BY project_id;
三、高级应用技巧
1. 处理NULL值
-- 跳过NULL值(默认行为)
GROUP_CONCAT(IFNULL(field, 'N/A'))
-- 包含NULL占位
GROUP_CONCAT(field SEPARATOR '|')
2. 动态设置长度
-- 会话级调整(最大1MB)
SET SESSION group_concat_max_len = 1024 * 1024;
3. 嵌套JSON输出(MySQL 8.0+)
SELECT
dept_id,
JSON_ARRAYAGG(
JSON_OBJECT('name', name, 'id', emp_id)
) AS member_json
FROM employees
GROUP BY dept_id;
4. 与CONCAT_WS配合
-- 智能处理空值
SELECT
GROUP_CONCAT(
CONCAT_WS(':',
NULLIF(first_name,''),
NULLIF(last_name,'')
)
SEPARATOR '\n'
) AS full_names
FROM users;
五、业务使用示例
<select id= "pageAlarmEvent" resultMap= "PageResultMap">
select
ae.id,
ae.event_name,
ae.rule_name,
ae.monitoring,
ae.warehouse_id,
ae.level,
ar.time_interval,
GROUP_CONCAT(an.title ORDER BY aen.id SEPARATOR ', ') AS notificationIdList,
ae.notification_time,
ae.start_time,
ae.end_time,
ae.is_next,
ae.event_status,
ae.update_user_id,
ae.update_time
FROM
alarm_event ae
LEFT JOIN
alarm_rule ar ON ae.rule_id = ar.id
LEFT JOIN
alarm_event_notification aen ON ae.id = aen.event_id and aen.is_delete = 0
LEFT JOIN
alarm_notification an ON aen.notification_id = an.id
<where>
ae.is_delete = 0
AND ae.company_id=#{companyId}
<!-- 添加筛选条件 -->
<if test="queryParam.warehouseId != null and queryParam.warehouseId != ''">
AND ae.warehouse_id = #{queryParam.warehouseId}
</if>
<if test="queryParam.tankId != null">
AND ae.tank_id = #{queryParam.tankId}
</if>
<if test="queryParam.level != null">
AND ae.level = #{queryParam.level}
</if>
<if test="queryParam.eventName != null and queryParam.eventName != ''">
AND ae.event_name LIKE CONCAT('%', #{queryParam.eventName}, '%')
</if>
<if test="queryParam.eventStatus != null">
AND ae.event_status = #{queryParam.eventStatus}
</if>
</where>
GROUP BY
ae.id,
ae.event_name,
ae.rule_name,
ae.monitoring,
ae.level,
ae.warehouse_id,
ar.time_interval,
ae.notification_time,
ae.start_time,
ae.end_time,
ae.is_next,
ae.event_status,
ae.update_user_id,
ae.update_time
<!-- 添加排序条件 -->
ORDER BY ae.update_time DESC
</select>
场景描述
某告警事件ID= "event_123"关联了3条通知:
aen.id an.title
88 温度过高
92 压力异常
95 阀门泄漏
执行过程
按aen.id 排序得到序列:88 → 92 → 95
提取对应an.title :温度过高 → 压力异常 → 阀门泄漏
用分隔符连接:"温度过高, 压力异常, 阀门泄漏"
最终结果
{
"id": "event_123",
"notificationIdList": "温度过高, 压力异常, 阀门泄漏"
}
2万+

被折叠的 条评论
为什么被折叠?



