mysql 数据列按照逗号转成行
前言:
由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式。即同一个列中存储了多个属性值(具体结构见下表)。
这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果。
表数据:
| ID | Value |
| 1 | tiny,small,big |
| 2 | small,medium |
| 3 | tiny,big |
期望得到结果:
| ID | Value |
| 1 | tiny |
| 1 | small |
| 1 | big |
| 2 | small |
| 2 | medium |
| 3 | tiny |
| 3 | big |
正文:

#需要处理的表
create table tbl_name (ID int ,mSize varchar(100));
insert into tbl_name values (1,'tiny,small,big');
insert into tbl_name values (2,'small,medium');
insert into tbl_name values (3,'tiny,big'); #用于循环的自增表
create table incre_table (AutoIncreID int);
insert into incre_table values (1);
insert into incre_table values (2);
insert into incre_table values (3);


select a.ID,substring_index(substring_index(a.mSize,',',b.AutoIncreID),',',-1)
from
tbl_name a
join
incre_table b
on b.AutoIncreID <= (length(a.mSize) - length(replace(a.mSize,',',''))+1)
order by a.ID;

原理分析:
这个join最基本原理是笛卡尔积。通过这个方式来实现循环。
以下是具体问题分析:
length(a.Size) - length(replace(a.mSize,',',''))+1 表示了,按照逗号分割后,改列拥有的数值数量,下面简称n
join过程的伪代码:
根据ID进行循环
{
判断:i 是否 <= n
{
获取最靠近第 i 个逗号之前的数据, 即 substring_index(substring_index(a.mSize,',',b.ID),',',-1)
i = i +1
}
ID = ID +1
}
总结:
这种方法的缺点在于,我们需要一个拥有连续数列的独立表(这里是incre_table)。并且连续数列的最大值一定要大于符合分割的值的个数。
例如有一行的mSize 有100个逗号分割的值,那么我们的incre_table 就需要有至少100个连续行。
当然,mysql内部也有现成的连续数列表可用。如mysql.help_topic: help_topic_id 共有504个数值,一般能满足于大部分需求了。
改写后如下:

select a.ID,substring_index(substring_index(a.mSize,',',b.help_topic_id+1),',',-1)
from
tbl_name a
join
mysql.help_topic b
on b.help_topic_id < (length(a.mSize) - length(replace(a.mSize,',',''))+1)
order by a.ID;
mysql 数据列按照逗号转成行的更多相关文章
- 如何正确选择MySQL数据列类型
MySQL数据列类型选择是在我们设计表的时候经常会遇到的问题,下面就教您如何正确选择MySQL数据列类型,供您参考学习. 选择正确的数据列类型能大大提高数据库的性能和使数据库具有高扩展性.在选择MyS ...
- 如何把mysql的列修改成行显示数据简单实现
如何把mysql的列修改成行显示数据简单实现 创建测试表: 1: DROP TABLE IF EXISTS `test`; 2: CREATE TABLE `test` ( 3: `year` int ...
- mysql数据库导出模型到powerdesigner,PDM图形窗口中显示数据列的中文注释
1,mysql数据库导出模型到powerdesigner 2,CRL+Shift+X 3,复制以下内容,执行 '******************************************** ...
- mysql 基本语法学习1(数据库、数据表、数据列的操作)
今天学习了一下mysql语法,并记录下来 1.mysql的数据库操作 /***1.操作数据库的语法 ***/ -- 1)显示所有数据库 -- show databases; -- 2)创建数据库 -- ...
- 设置mysql数据表列自动递增以及数据行插入操作
创建mysql数据表,设置id列递增.主键create table running_log ( id int primary key auto_increment, routename varchar ...
- Mysql的数据列类型效率
1. 能短就不要长.(磁盘I/O少一些) 比如固定 长度的CHAR数据列,定义 CHAR(40),而不是 CHAR(255); 比如MEDIUMINT代替BIGINT,数据表就小一些, 值的处理 ...
- 关于MySQL数据导出导入
工具 mysqlmysqldump 应用举例 导出 导出全库备份到本地的目录 mysqldump -u$USER -p$PASSWD -h127.0.0.1 -P3306 --routines --d ...
- MySQL数据导出导入【转】
MySQL基础 关于MySQL数据导出导入的文章,目的有二: 1.备忘 2.供开发人员测试 工具 mysqlmysqldump 应用举例 导出 导出全库备份到本地的目录 mysqldump -u$US ...
- Sqoop将mysql数据导入hbase的血与泪
Sqoop将mysql数据导入hbase的血与泪(整整搞了大半天) 版权声明:本文为yunshuxueyuan原创文章.如需转载请标明出处: https://my.oschina.net/yunsh ...
随机推荐
- 一键安装Redmine
群英汇·项目管理系统:http://www.ossxp.com/HelpCenter/00040_Redmine 其中包含中文说明及管理手册 一键安装下载:http://bitnami.org/sta ...
- android 控件注意点
控件一:listview 问题一:当listview的item中存在按钮这种控件时 item点击不能响应问题? 解决方案:在item的自定义控件的最外层空间 上添加属性 android:descend ...
- hibernate子查询
对于支持子查询的数据库,Hibernate支持在查询中使用子查询.一个子查询必须被圆括号包围起来(经常是SQL聚集函数的圆括号). 甚至相互关联的子查询(引用到外部查询中的别名的子查询)也是允许的. ...
- glibc漏洞监测并修复
[CVE 2015-0235: GNU glibc gethostbyname 缓冲区溢出漏洞 ]全面爆发,该漏洞的产生是Qualys公司在进行内部代码审核时,发现了一个在GNU C库(glibc)中 ...
- Metrics-Java版的指标度量工具
介绍 Metrics是一个给JAVA服务的各项指标提供度量工具的包,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控,同时,Metrics能够很好的跟Ganlia.Gra ...
- Spring Security(17)——基于方法的权限控制
目录 1.1 intercept-methods定义方法权限控制 1.2 使用pointcut定义方法权限控制 1.3 使用注解定义方法权限控制 1.3.1 JSR-25 ...
- 序列化与反序列化总结(Serializable和Parcelable)
序列化是指将对象的状态信息转换为可以存储或传输的形式的过程. 在Java中创建的对象,只要没有被回收就可以被复用,但是,创建的这些对象都是存在于JVM的堆内存中,JVM处于运行状态时候,这些对象可以复 ...
- F9 开发之左树右表中的左树
1 首先在前端应用树树控件 <div class="fui-left"> <div role="head" title="地区选择& ...
- [kuangbin带你飞]专题六 最小生成树 POJ 1287 Networking
最小生成树模板题 跑一次kruskal就可以了 /* *********************************************** Author :Sun Yuefeng Creat ...
- iOS编程中throttle那些事
不知道大家对throttle这个单词是否看着眼熟,还是说对这个计算机基础概念有很清晰的了解了.今天就来聊聊和throttle相关的一些技术场景. 定义 我经常有一种感觉,对于英语这门语言的语感,会影响 ...