zoukankan      html  css  js  c++  java
  • MySQL列转行

    文章转自别人的博客

    为了做备份(把别人的文章内容抄了一遍):

    #需要处理的表
    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;
    
  • 相关阅读:
    MEAN: AngularJS + NodeJS的REST API开发教程
    什么是MEAN全堆栈javascript开发框架
    fputcsv 导出excel,解决内存、性能、乱码、科学计数法问题
    React 高德地图画点画区域放大缩小
    React 拖动布局
    React+TypeScript搭建项目
    js 运算符优先级
    for...in 与 for...of
    前端面试点记录
    Vue 高德地图 路径规划 画点
  • 原文地址:https://www.cnblogs.com/andysd/p/6020712.html
Copyright © 2011-2022 走看看