【MySql 项目实战优化】多行数据转化为同一行多列显示

在我的工作中,接到过这么一个需求,需要合并纵向的数据为 1 条记录显示出来。
业务场景
用业务上的说法,我这里有 1 个物料,其中有 n 个属性,每个属性配置有是否显示的开关,对于这个物料的 n 个属性,就是 n 条记录存储在这个表中;现在就需要对这个表按物料编码分组,分组后的数据,提取出物料的属性和配置,作为单条记录显示,画一个大概的示意图

这需求的理由是大量的数据拉出来后,上方的模式阅读数据会非常的不直观
这种转化的操作,我们可以使用 java 来处理,拉取到全部的数据后,再根据物料编码进行分组后合并数据即可;但,这次我选择在 mysql 中处理好,直接拿到需要的数据
业务中用到的技能
左连接获取到其余表中的数据
case
将状态数据转化为文本描述,类似于1 -> 启用, 0 -> 禁用
表多层嵌套查询
表数据分组查询 +
group_concat
连接目标字段合并到 1 条记录中substring_index
,根据分隔符截取字符串replace
替换字符串数据
从内往外开始查询处理为临时表
联表查询准备基本数据
在这一步,获取到全部的基础数据,同时将标记转化位文本描述,将操作后获得的临时表标记为 b
临时表的效果如下:

临时表以 code 分组合并数据
在临时表 b
的基础上,根据 code
分组将后面几列的数据通过 group_concat
合并到 1 个字段上
这次操作获得的临时表标记为 c
现在所有的数据已经可以按照 code
显示为单条记录,效果如下:

拆分数据到多列
在临时表 c
的基础上,我们对目标字段进行截取,每一列都是截取自目标字段中的一部分内容
截取后的示意草图:

这里就用到了 REPLACE + SUBSTRING_INDEX
组合处理得到切割后对应下标的数据
sql 执行后的效果如下:

完美解决问题
SUBSTRING_INDEX 功能
在这个问题的处理过程中,用到了一个核心的方法 SUBSTRING_INDEX(str, delim, count)
,功能为字符串截取
但又不同于常规的理解,传入的下标 count
并不是选取 str
截取后对应的下标字符;可以这么理解,count
指从左往右匹配指定次数的分隔符 delim
,最后一次匹配时会记录下那个分隔符对应的字符串下标位置 n
,最后结果为 str
的前 n
个字符(不包括末尾的分隔符)
来个形象的例子:
版权声明: 本文为 InfoQ 作者【安逸的咸鱼】的原创文章。
原文链接:【http://xie.infoq.cn/article/79d37d9d4c4909298a885cd94】。文章转载请联系作者。
评论