# MySQL怎么实现多行转一行 ## 引言 在数据库操作中,我们经常会遇到需要将多行数据合并成一行的场景。例如将某个分组下的多条记录合并为一条记录展示,或将多行文本拼接成单个字符串。MySQL提供了多种实现方式,本文将详细介绍5种常用方法及其适用场景。 ## 一、GROUP_CONCAT函数 ### 1.1 基本语法 ```sql GROUP_CONCAT([DISTINCT] column_name [ORDER BY sort_column ASC/DESC] [SEPARATOR '分隔符'])
-- 基础用法 SELECT department_id, GROUP_CONCAT(employee_name) AS employees FROM employees GROUP BY department_id; -- 带分隔符和排序 SELECT product_id, GROUP_CONCAT(DISTINCT tag_name ORDER BY tag_id SEPARATOR '|') FROM product_tags GROUP BY product_id;
group_concat_max_len
参数调整)SELECT user_id, (SELECT GROUP_CONCAT(order_id) FROM orders WHERE user_id = u.user_id) AS order_list FROM users u;
SELECT department, CONCAT_WS(',', MAX(CASE WHEN seq = 1 THEN name END), MAX(CASE WHEN seq = 2 THEN name END) ) AS members FROM ( SELECT department, name, @rn := IF(@dept = department, @rn + 1, 1) AS seq, @dept := department FROM employees, (SELECT @rn := 0, @dept := '') r ORDER BY department, name ) t GROUP BY department;
DELIMITER // CREATE PROCEDURE concat_employee_names(IN dept_id INT) BEGIN DECLARE result TEXT DEFAULT ''; DECLARE done INT DEFAULT FALSE; DECLARE emp_name VARCHAR(100); DECLARE cur CURSOR FOR SELECT name FROM employees WHERE department_id = dept_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO emp_name; IF done THEN LEAVE read_loop; END IF; SET result = CONCAT(result, emp_name, ','); END LOOP; CLOSE cur; SELECT dept_id AS department_id, LEFT(result, LENGTH(result)-1) AS employee_list; END // DELIMITER ;
SELECT department_id, JSON_ARRAYAGG(employee_name) AS json_employee_array FROM employees GROUP BY department_id;
SELECT project_id, JSON_OBJECTAGG(employee_id, hours_worked) AS team_hours FROM project_assignments GROUP BY project_id;
SELECT IFNULL(department, 'ALL') AS department, GROUP_CONCAT(DISTINCT position) AS positions, COUNT(*) AS employee_count FROM employees GROUP BY department WITH ROLLUP;
方法 | 适用版本 | 性能表现 | 功能复杂度 |
---|---|---|---|
GROUP_CONCAT | 4.1+ | ★★★★☆ | ★★☆☆☆ |
子查询拼接 | 所有版本 | ★★☆☆☆ | ★★★☆☆ |
存储过程 | 所有版本 | ★★★☆☆ | ★★★★☆ |
JSON函数 | 5.7+ | ★★★★☆ | ★★★☆☆ |
WITH ROLLUP | 4.1+ | ★★★☆☆ | ★★★☆☆ |
SELECT product_id, GROUP_CONCAT( CONCAT(attr_name, ':', attr_value) SEPARATOR '; ' ) AS product_attributes FROM product_specs GROUP BY product_id;
SELECT u.user_id, u.username, GROUP_CONCAT(r.role_name ORDER BY r.role_level DESC) AS roles FROM users u JOIN user_roles ur ON u.user_id = ur.user_id JOIN roles r ON ur.role_id = r.role_id GROUP BY u.user_id, u.username;
-- 临时设置更大的长度限制 SET SESSION group_concat_max_len = 1000000; SELECT GROUP_CONCAT(...);
-- 使用REPLACE处理分隔符冲突 SELECT GROUP_CONCAT(REPLACE(text_field, ',', ',') SEPARATOR ',') FROM table;
MySQL实现多行转一行主要有以下几种方式: 1. 优先推荐:GROUP_CONCAT(简单高效) 2. 复杂逻辑:存储过程(灵活可控) 3. 现代方案:JSON函数(结构化输出) 4. 兼容方案:子查询拼接(低版本兼容)
根据实际业务需求选择合适的方法,同时注意处理大数据量时的性能问题。对于超大数据集,建议在应用层进行处理。 “`
注:本文实际约1500字,完整版可根据需要扩展具体示例和性能测试数据。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。