在MySQL内部转置数据 - 从列值到行值

Ser*_*rge -2 mysql pivot

让我们说在我的情况下,我有一个像这样的表:

id  group_id    text        data    empty1  empty2  empty3  empty4  empty5

1   20      AB      data1
2   20      AB      data2
3   21      AC      data3
4   20      AB      data4
5   21      AC      data5
6   22      AD      data6
7   22      AD      data7
8   22      AD      data8
9   23      AF      data9
Run Code Online (Sandbox Code Playgroud)

如您所见 - 字段'text'包含一些相同的数据 - 根据字段'group_id'."text"是字母数字和"group_id"的唯一区别是数字.字段'数据'包含各种文本信息(varchar(255))

是否有可能并且如何处理MySQL内部的表以根据group_id将值从"data"字段复制(或移动)到"empty"字段,如下所示:

id  group_id    text        data        empty1      empty2      empty3  empty4  empty5

1   20      AB      data1       data1       data2       data4
2   20      AB      data2
3   21      AC      data3       data3       data5
4   20      AB      data4
5   21      AC      data5
6   22      AD      data6       data6       data7       data8
7   22      AD      data7
8   22      AD      data8
9   23      AF      data9       data9
Run Code Online (Sandbox Code Playgroud)

可能是首先填写所有内容更容易 - 我的意思是

id  group_id    text        data        empty1      empty2      empty3  empty4  empty5

1   20      AB      data1       data1       data2       data4
2   20      AB      data2       data1       data2       data4
Run Code Online (Sandbox Code Playgroud)

并且作为最后一步 - 只需删除基于group_id的重复项 - 这样最终我们就有了一个清晰的FINAL表

id  group_id    text        data        empty1      empty2      empty3  empty4  empty5

1   20      AB      data1       data1       data2       data4
3   21      AC      data3       data3       data5
6   22      AD      data6       data6       data7       data8
9   23      AF      data9       data9
Run Code Online (Sandbox Code Playgroud)

Tar*_*ryn 7

您可以使用变量和聚合函数将数据行转换为列,从而将数据转换为所需的格式.

以您希望的格式获取数据的基本语法是:

select d.id,
  d.group_id,
  d.text,
  t.data,
  d.empty1,
  d.empty2,
  d.empty3,
  d.empty4,
  d.empty5
from yourtable t
inner join 
(
  select min(id) id,
    group_id,
    text,
    max(case when row=1 then data end) empty1,
    max(case when row=2 then data end) empty2,
    max(case when row=3 then data end) empty3,
    max(case when row=4 then data end) empty4,
    max(case when row=5 then data end) empty5
  from
  (
    select id, 
      group_id,
      text,
      data,
      @row:=case 
              when @pg=group_id and @pt=text
              then @row
              else 0 end +1 row,
      @pg:=group_id,
      @pt:=text
    from yourtable 
    cross join
    (
      select @row:=0, @pg:=0, @pt:=null
    ) c
    order by group_id, text, id
  ) src
  group by group_id, text
  order by group_id, text, id
) d
  on t.id = d.id
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.此查询将为您提供结果:

| ID | GROUP_ID | TEXT |  DATA | EMPTY1 | EMPTY2 | EMPTY3 | EMPTY4 | EMPTY5 |
-----------------------------------------------------------------------------
|  1 |       20 |   AB | data1 |  data1 |  data2 |  data4 | (null) | (null) |
|  3 |       21 |   AC | data3 |  data3 |  data5 | (null) | (null) | (null) |
|  6 |       22 |   AD | data6 |  data6 |  data7 |  data8 | (null) | (null) |
|  9 |       23 |   AF | data9 |  data9 | (null) | (null) | (null) | (null) |
Run Code Online (Sandbox Code Playgroud)

  • @Serge:但是如果你继续问"我怎么解决这个问题?","我怎么解决这个问题?",这不是在学习.你已经获得了一个*工作解决方案*,所以请花点时间弄清楚它是如何工作的,特别是它的每一点都能最终归还你想要的结果,直到你完全掌控它是什么继续在查询的每个阶段.*那*会学习,而**实际上会帮助你提出*你自己*的想法. (2认同)