zoukankan      html  css  js  c++  java
  • 【mysql】逗号分割字段的行列转换

      由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式,即同一个列中存储了多个属性值。这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果:这里使用substring_index函数进行处理

    建表语句:

     1 DROP table if EXISTS tbl_name;
     2 CREATE TABLE tbl_name(
     3     id       int(11)    not null auto_increment,
     4     userName varchar(100)    not null,
     5 PRIMARY KEY(id)
     6 )
     7 ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
     8 
     9 insert into tbl_name values (1,'a,aa,aaa');
    10 insert into tbl_name values (2,'b,bb');
    11 insert into tbl_name values (3,'c,cc');

    如下图:

    sql语句:

    1 SELECT a.id,SUBSTRING_INDEX(SUBSTRING_INDEX(a.userName,',',b.help_topic_id+1),',',-1) as name  
    2 from tbl_name a left join mysql.help_topic b 
    3 on b.help_topic_id < (LENGTH(a.userName)-LENGTH(REPLACE(a.userName,',',''))+1) 
    4 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个数值,一般能满足于大部分需求了。

    作者:howtosay
             
    放牛娃的个人笔记整理,每天记录一点点,进步一点点
  • 相关阅读:
    25-javaweb接入支付宝支付接口
    4-js 函数
    24-filter-拦截器
    23-新建maven 项目
    22-maven-安装与配置
    15-matlab矩阵运用
    2018.7.18 div,section,article的区别和使用
    2018.7.17 牛客网训练
    2018.7.16常用推荐算法
    2018.7.15 解决css中input输入框点击时去掉外边框方法
  • 原文地址:https://www.cnblogs.com/hongzm/p/8145149.html
Copyright © 2011-2022 走看看