
这种转换不仅有助于更好地理解和展示数据,还能提升数据处理的效率和灵活性
本文将详细介绍 MySQL 数据转多行的几种常见方法和技巧,帮助你在实际工作中更加高效地操作数据
一、引言 在 MySQL 中,数据通常以表格形式存储,每一行代表一条记录,每一列代表一个字段
然而,在某些情况下,数据以复杂或嵌套的形式存储在一行中,例如 JSON字符串或逗号分隔的字符串
将这些数据转换为多行,可以极大地简化后续的数据处理和分析工作
二、常见的数据转多行场景 1.逗号分隔字符串:某些字段中存储的是以逗号分隔的字符串,需要将每个值拆分为单独的行
2.JSON 数据:MySQL 5.7 及以上版本支持 JSON 数据类型,可以将 JSON数组中的每个元素拆分为单独的行
3.递归查询:在层级结构数据中,如组织架构或分类目录,需要将层级数据展开为多行
三、逗号分隔字符串转多行 在处理逗号分隔字符串时,通常使用 MySQL 自带的字符串函数和递归公用表表达式(CTE)来实现转换
示例数据 假设有一个名为`employees` 的表,其中有一个字段`skills` 存储的是以逗号分隔的技能列表: sql CREATE TABLE employees( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), skills VARCHAR(255) ); INSERT INTO employees(name, skills) VALUES (Alice, Java,SQL,Python), (Bob, HTML,CSS,JavaScript), (Charlie, MySQL,PostgreSQL,Oracle); 使用递归 CTE拆分字符串 MySQL8.0及以上版本支持递归 CTE,可以通过递归 CTE 和字符串函数来拆分字符串: sql WITH RECURSIVE split_skills AS( SELECT id, name, SUBSTRING_INDEX(skills, ,,1) AS skill, SUBSTRING(skills, INSTR(skills,,) +1) AS remaining_skills, 1 AS level FROM employees WHERE skills <> UNION ALL SELECT id, name, SUBSTRING_INDEX(remaining_skills, ,,1), IF(INSTR(remaining_skills,,) >0, SUBSTRING(remaining_skills, INSTR(remaining_skills,,) +1),), level +1 FROM split_skills WHERE remaining_skills <> ) SELECT id, name, skill FROM split_skills ORDER BY id, level; 上述查询首先通过`SUBSTRING_INDEX` 函数获取第一个技能,然后通过递归 CTE逐步拆分剩余的字符串,直到没有剩余字符串为止
四、JSON 数据转多行 MySQL5.7及以上版本引入了 JSON 数据类型和相关的函数,可以方便地处理 JSON 数据
示例数据 假设有一个名为`projects` 的表,其中有一个字段`technologies` 存储的是 JSON数组: sql CREATE TABLE projects( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), technologies JSON ); INSERT INTO projects(name, technologies) VALUES (Project A, 【Java, Spring, MySQL】), (Project B, 【React, Node.js, Express】), (Project C, 【Python, Django, PostgreSQL】); 使用 JSON_TABLE 函数 MySQL8.0引入了`JSON_TABLE` 函数,可以将 JSON 数据转换为关系表: sql SELECT p.id, p.name, jt.technology FROM projects p, JSON_TABLE(p.technologies, $【】 COLUMNS ( technology VARCHAR(100) PATH $ )) jt; `JSON_TABLE` 函数将`technologies`字段中的 JSON数组展开为关系表,每一行代表数组中的一个元素
使用 JSON_EXTRACT 和递归 CTE 在 MySQL8.0之前的版本中,可以使用`JSON_EXTRACT` 和递归 CTE(如果可用)来实现类似的功能: sql WITH RECURSIVE json_array_elements AS( SELECT id, name, JSON_EXTRACT(technologies, $【0】) AS technology, JSON_LENGTH(technologies) AS total_elements, 1 AS level FROM projects WHERE JSON_LENGTH(technologies) >0 UNION ALL SELECT id, name, JSON_EXTRACT(technologies, CONCAT($【, level,】)) AS technology, total_elements, level +1 FROM json_array_elements WHERE level < total_elements ) SELECT id, name, JSON_UNQUOTE(JSON_EXTRACT(technology, $)) AS technology FROM json_array_elements ORDER BY id, level; 这个查询使用递归 CTE逐步提取 JSON数组中的每个元素,直到遍历完所有元素
五、递归查询转多行 在处理层级结构数据时,如组织架构或分类目录,可以使用递归 CTE 将层级数据展开为多行
示例数据 假设有一个名为`categories` 的表,存储的是商品分类的层级结构: sql CREATE TABLE categories( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), parent_id INT, FOREIGN KEY(parent_id) REFERENCES categories(id) ); INSERT INTO categories(name, parent_id) VALUES (Electronics, NULL), (Laptops,1), (Desktops,1), (Gaming Laptops,2), (Ultrabooks,2), (Smartphones,1), (Apple,6), (Samsung,6); 使用递归 CTE展开层级结构 sql WITH RECURSIVE category_hierarchy AS( SELECT id, name, pa
详解MySQL主从复制机制
MySQL数据转多行技巧揭秘
MySQL主键断层解决方案:如何有效管理与设置
MySQL数据库:如何查询10天前数据
MySQL中间表技巧:避免JOIN的高效策略
MySQL无法通过IP访问,解决方案!
MySQL触发器:高效更新数据技巧
详解MySQL主从复制机制
MySQL主键断层解决方案:如何有效管理与设置
MySQL数据库:如何查询10天前数据
MySQL无法通过IP访问,解决方案!
MySQL中间表技巧:避免JOIN的高效策略
MySQL触发器:高效更新数据技巧
MySQL分类存储与冗余设计解析
MySQL安装后:如何顺利连接到服务器的实用指南
双版本MySQL安装指南
MySQL安装:选对文件一步到位
免费主机MySQL远程访问设置指南
Linux MySQL主从切换实战指南