【问题标题】:mysql pivot table with string values带有字符串值的mysql数据透视表
【发布时间】:2018-06-22 14:28:45
【问题描述】:

我有一个像这样只有两列的表格

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..) 或 group by,但它不起作用。是否有任何 mysql 查询来获得这样的表?请帮忙。谢谢。

【问题讨论】:

  • 您的示例表缺少一列,该列将说明每个数据点将映射到透视输出中的哪一行。翻译:没有足够的信息来回答这个问题。
  • 这是一种在应用程序语言中更容易解决的问题,而不是 SQL。

标签: mysql sql pivot pivot-table aggregate


【解决方案1】:

根据您使用的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

【讨论】:

  • 你用的是什么mysql版本?我用的是 mysql 5.7
  • @Yarp 正如我所提到的,旧版本的mysql 不支持row_number。您需要改用user-defined variables。这是一个有效的小提琴:db-fiddle.com/f/skbKMWPCGJFLURLmkcouD4/1
  • 第一个解决方案使用的具体版本是什么?它看起来更优雅。
【解决方案2】:

你不需要使用 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;

【讨论】:

  • 我的错,我发布的那个返回 NULL 但有八行。我只是混合了这么多解决方案,但没有找到合适的解决方案
  • 它可以工作,但返回的行数与第一个表相同,我最多只需要四行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
  • 1970-01-01
  • 2019-05-14
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2012-07-13
相关资源
最近更新 更多