【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個數值,一般能滿足於大部分需求了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM