【mysql】逗号分割字段的行列转换
2023-12-01 12:40:56
由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式,即同一个列中存储了多个属性值。这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果:这里使用substring_index函数进行处理
建表语句:
DROP table if EXISTS tbl_name;
CREATE TABLE tbl_name(
id int(11) not null auto_increment,
userName varchar(100) not null,
PRIMARY KEY(id)
)
ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; insert into tbl_name values (1,'a,aa,aaa');
insert into tbl_name values (2,'b,bb');
insert into tbl_name values (3,'c,cc');
如下图:
sql语句:
SELECT a.id,SUBSTRING_INDEX(SUBSTRING_INDEX(a.userName,',',b.help_topic_id+1),',',-1) as name
from tbl_name a left join mysql.help_topic b
on b.help_topic_id < (LENGTH(a.userName)-LENGTH(REPLACE(a.userName,',',''))+1)
ORDER BY a.id;
执行结果:
分析如下:
LENGTH(a.userName)-LENGTH(REPLACE(a.userName,',',''))+1
表示了按逗号分割后,获得行转成列的数量,以下简称n;
根据id进行循环 {
判断:i 是否 <= n
{
获取最靠近第 i 个逗号之前的数据, 即 SUBSTRING_INDEX(SUBSTRING_INDEX(a.userName,',',b.help_topic_id+1),',',-1)
i = i +1
}
id = id +1
}
总结:
这种方法的缺点在于,我们需要一个拥有连续数列的独立表。并且连续数列的最大值一定要大于符合分割的值的个数。当然,mysql内部也有现成的连续数列表可用。如mysql.help_topic: help_topic_id 共有504个数值,一般能满足于大部分需求了。
最新文章
- 移动端之Android开发的几种方式的初步体验
- CentOS7 编译安装 nginx-1.10.0
- C++学习笔记 知识集锦(二)
- wpf listbox 内的内容显示问题,需要设置里面的itemsPresenter
- Python之路【第二篇】:Python基础
- html下拉菜单的实现
- TextInfo
- 响应式注意要添加“视口”约束标记---viewport
- 2016 Multi-University Training Contest 2 第一题Acperience
- iOS 语音识别使用讯飞报错
- JavaScript语法细节——引用与复制
- hdu4597 Play Game 区间DP
- client和nginx简易交互过程
- [CQOI2009]dance跳舞
- c#缓存技术(Dictionary)
- 设计模式学习心得<;桥接模式 Bridge>;
- 第五节,损失函数:MSE和交叉熵
- 查看浏览器中Cookie信息
- LeetCode--108--将有序数组转化为二叉搜索树
- js 判断哪个获得焦点