由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式,即同一个列中存储了多个属性值。这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果:这里使用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个数值,一般能满足于大部分需求了。

最新文章

  1. 移动端之Android开发的几种方式的初步体验
  2. CentOS7 编译安装 nginx-1.10.0
  3. C++学习笔记 知识集锦(二)
  4. wpf listbox 内的内容显示问题,需要设置里面的itemsPresenter
  5. Python之路【第二篇】:Python基础
  6. html下拉菜单的实现
  7. TextInfo
  8. 响应式注意要添加“视口”约束标记---viewport
  9. 2016 Multi-University Training Contest 2 第一题Acperience
  10. iOS 语音识别使用讯飞报错
  11. JavaScript语法细节——引用与复制
  12. hdu4597 Play Game 区间DP
  13. client和nginx简易交互过程
  14. [CQOI2009]dance跳舞
  15. c#缓存技术(Dictionary)
  16. 设计模式学习心得&lt;桥接模式 Bridge&gt;
  17. 第五节,损失函数:MSE和交叉熵
  18. 查看浏览器中Cookie信息
  19. LeetCode--108--将有序数组转化为二叉搜索树
  20. js 判断哪个获得焦点

热门文章

  1. JavaSE assert断言的学习
  2. cs231n(三) 误差反向传播
  3. Github Upload Large File 上传超大文件
  4. thinkphp5中使用PHPExcel(转载)
  5. metasploit 常用命令备忘
  6. 主流框架的搭建(VUE,React)
  7. python中文分词库——pynlpir
  8. SQL 资源整理
  9. 求最小生成树的kruskal算法
  10. SVN和Git对比梳理