带有字符串值的mysql数据透视表

时间:2018-06-22 14:28:45

标签: mysql sql pivot pivot-table aggregate

我有一个只有两列的表格

mysql> select * from stuff_table;
+------+-------+
| name | stuff |
+------+-------+
| John | shoes |
| Jim  | bag   |
| Ely  | book  |
| Tom  | bag   |
| Will | shoes |
| Pitt | book  |
| Dean | bag   |
| Luke | bag   |
+------+-------+

我尝试了很多发现的解决方案

select distinct
max(case when stuff='shoes' then name else name is null) end as shoes,
max(case when stuff='bag' then name else name is null end) as bag,
max(case when stuff='book' then name else name is null end) as book
from stuff_table;

但是我刚得到这个

+-------+------+------+
| shoes | bag  | book |
+-------+------+------+
| Will  | Tom  | Pitt |
+-------+------+------+

相反,我想得到这个

+-------+------+------+
| shoes | bag  | book |
+-------+------+------+
| John  | Jim  | Ely  |
| Will  | Tom  | Pitt |
| NULL  | Dean | NULL |
| NULL  | Luke | NULL |
+-------+------+------+

我也尝试过sum(case ...)或if(case ..)或分组方式,但是它不起作用。有没有MySQL查询来获得这样的表?请帮助。谢谢。

2 个答案:

答案 0 :(得分:0)

您不需要使用else,并且在max函数之外具有结束符:

select distinct
max(case when stuff='shoes' then name end ) as shoes,
max(case when stuff='bag' then name  end) as bag,
max(case when stuff='book' then name  end) as book
from stuff_table;

答案 1 :(得分:0)

根据您使用的mysql的版本,以下是一种方法,即每组建立一个row_number,然后使用按该行号分组的conditional aggregation

select 
    rn, 
    max(case when stuff = 'bag' then name end) 'bag',
    max(case when stuff = 'book' then name end) 'book',
    max(case when stuff = 'shoes' then name end) 'shoes' 
from (
  select *, row_number() over (partition by stuff order by name) rn
  from stuff_table
) t
group by rn

由于您使用的是mysql的旧版本,因此需要使用user-defined variables来确定行号。其余的工作原理相同。这是一个示例:

select 
    rn, 
    max(case when stuff = 'bag' then name end) 'bag',
    max(case when stuff = 'book' then name end) 'book',
    max(case when stuff = 'shoes' then name end) 'shoes' 
from (
  select *, 
  ( case stuff 
         when @curStuff
         then @curRow := @curRow + 1 
         else @curRow := 1 and @curStuff := stuff 
   end
  ) + 1 AS rn
  from stuff_table, (select @curRow := 0, @curStuff := '') r
  order by stuff
) t
group by rn