MySql:将列数据转换为行

时间:2018-03-14 09:52:59

标签: mysql unpivot

我在mysql中有一个表,如下所示。

id  cust_id date    data

1   1   1/1/2018    a b c d e f g

2   1   2/1/2018    h I j k l m n 

在这个示例中,数据列具有像b c d一样的空间分隔的巨大数据,我想像下面的行一样显示案例

id  cust_id date    data

1   1   1/1/2018    a

1   1   1/1/2018    b

1   1   1/1/2018    c

1   1   1/1/2018    d

2   2   2/1/2018    h

2   2   2/1/2018    i

2   2   2/1/2018    j

2   2   2/1/2018    k

我检查了一些选项,比如使用unpivot功能,但无法实现我的输出。 在此先感谢!!

1 个答案:

答案 0 :(得分:0)

select
  tablename.id,
  tablename.date
  ,SUBSTRING_INDEX(SUBSTRING_INDEX(tablename.data, ' ', numbers.n), ' ', -1) name
from
  (
    SELECT @row := @row + 1 as n FROM 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t1,
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2,
    (SELECT @row:=0) r
  ) numbers INNER JOIN Table1 tablename
  on CHAR_LENGTH(tablename.data)
     -CHAR_LENGTH(REPLACE(tablename.data, ' ', ''))>=numbers.n-1
order by
  id, n

检查输出链接

  

http://sqlfiddle.com/#!9/fa0dcb/1

<强>说明: 首先查看内部查询,即

select 0 
union all 
select 1 
union all 
select 3 
union all 
select 4 
union all 
select 5 
union all 
select 6 
union all 
select 6 
union all 
select 7 
union all 
select 8 
union all 
select 9

这将生成一个包含10个数字的10行表。

现在是另一个查询:

 SELECT @row := @row + 1 as n FROM 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t1

由于以上查询是从下表生成行号,因此&#39; t&#39;和表&#39; t1&#39;由&#39;,&#39;分隔意味着他们正在生产总行数的笛卡尔积。 例如:t有10行,t1也有10行,所以笛卡尔积产生100行。所以@row变量增加了100次,并从1到100给出100行100个数字。

以下查询:

SUBSTRING_INDEX(SUBSTRING_INDEX(tablename.data, ' ', numbers.n), ' ', -1)

这个将采取&#34; a b c d e f g h&#34;一个接一个。

例如: 拿numbers.n = 1 然后内部substring_index将找到第一个空格的索引,并将在该索引之前返回字符串,即'a' 然后外部substring_index将从结果字符串的末尾找到空格,并将给出字符串中的最后一个字符,即'a'

现在,如果你 拿numbers.n = 2 然后内部substring_index将找到第一个空格的索引,并将在该索引之前返回字符串,即'a b' 然后外部substring_index将从结果字符串的末尾找到空格,并将给出字符串中的最后一个字符,即'b'

总是尝试像这样分解查询,您将能够以更简单的方式理解查询。