MySQL中如何使用substring_index拆分表中字符串值获取全部关联任务
问题原因
现有查询仅返回1条结果,原因有三点:
- 存在字段拼写错误:
projects.tak应为projects.task substring_index(projects.task,":",-1)只会截取冒号分隔字符串的最后一段,仅能拿到最后一个任务ID- 没有对多值的task字段做行展开,无法返回多行关联结果
最简通用实现方案(兼容绝大多数MySQL版本)
直接将task字段的冒号替换为逗号,用FIND_IN_SET函数关联任务表即可,写法简洁易维护:
SELECT p.id AS proID, p.name, t.name AS taskName FROM projects p INNER JOIN tasks t ON FIND_IN_SET(t.id, REPLACE(p.task, ':', ',')) WHERE p.id = 3;
其他可选实现方案
MySQL 8.0+ 递归CTE实现
如果需要处理单项目关联任务数极多的场景,可以用递归CTE拆分字符串:
WITH RECURSIVE split_ids AS ( SELECT id AS proID, name, SUBSTRING_INDEX(task, ':', 1) AS task_id, SUBSTRING(task, LENGTH(SUBSTRING_INDEX(task, ':', 1)) + 2) AS remaining_task FROM projects WHERE id = 3 UNION ALL SELECT proID, name, SUBSTRING_INDEX(remaining_task, ':', 1) AS task_id, SUBSTRING(remaining_task, LENGTH(SUBSTRING_INDEX(remaining_task, ':', 1)) + 2) AS remaining_task FROM split_ids WHERE remaining_task != '' ) SELECT s.proID, s.name, t.name AS taskName FROM split_ids s LEFT JOIN tasks t ON s.task_id = t.id;
低版本MySQL辅助数字表实现
如果数据库版本不支持递归CTE,可以预先创建存储连续数字的辅助表nums(值覆盖单个项目最多关联任务数即可),再执行查询:
SELECT p.id AS proID, p.name, t.name AS taskName FROM projects p JOIN nums n ON n.n <= LENGTH(p.task) - LENGTH(REPLACE(p.task, ':', '')) + 1 LEFT JOIN tasks t ON t.id = SUBSTRING_INDEX(SUBSTRING_INDEX(p.task, ':', n.n), ':', -1) WHERE p.id = 3;
返回结果
以上方案执行后均会得到预期结果:
| proID | name | taskName |
|---|---|---|
| 3 | pro_3 | task_2 |
| 3 | pro_3 | task_3 |
| 3 | pro_3 | task_4 |
内容的提问来源于stack exchange,提问作者flash
相关产品推荐
相关产品推荐

