gpt4 book ai didi

Mysql查询在两列的基础上动态将行转列

转载 作者:可可西里 更新时间:2023-11-01 06:31:42 25 4
gpt4 key购买 nike

我关注了一个 question这里使用Mysql查询动态地将行转换为列。这工作正常,但我需要根据两列进行转换,

上面链接中提到的查询适用于单个列“数据”,但我想适用于“数据”和“价格”两列。

我在这里添加了一个例子,

给定一张表A,它看起来像

Table A

| id|order|data|item|Price|
-----+-----+----------------
| 1| 1| P| 1 | 50 |
| 1| 1| P| 2 | 60 |
| 1| 1| P| 3 | 70 |
| 1| 2| Q| 1 | 50 |
| 1| 2| Q| 2 | 60 |
| 1| 2| Q| 3 | 70 |
| 2| 1| P| 1 | 50 |
| 2| 1| P| 2 | 60 |
| 2| 1| P| 4 | 80 |
| 2| 3| S| 1 | 50 |
| 2| 3| S| 2 | 60 |
| 2| 3| S| 4 | 80 |

我喜欢编写如下所示的查询:

Result Table

| id|order1|order2|order3|item1|item2|item3|item4|
-----+-----+---------------------------------------
| 1| P | Q | | 50 | 60 | 70 | |
| 2| P | | S | 50 | 60 | | 80 |

我曾尝试创建两个不同的查询,然后通过连接来实现此目的,但这可能不是一个好的解决方案。任何人都可以提出与上面链接中提到的相同的解决方案。

谢谢

最佳答案

如果您对 orderitem 都有已知数量的值,那么您可以将查询硬编码为:

select id,
max(case when `order` = 1 then data end) order1,
max(case when `order` = 2 then data end) order2,
max(case when `order` = 3 then data end) order3,
max(case when item = 1 then price end) item1,
max(case when item = 2 then price end) item2,
max(case when item = 3 then price end) item3,
max(case when item = 4 then price end) item4
from tableA
group by id;

参见 Demo .但是您将遇到的部分问题是因为您正在尝试转换多列数据。为了获得最终结果,我的建议是先取消数据透视。 MySQL 没有 unpivot 函数,但您可以使用 UNION ALL 将多对列转换为行。 unpivot 的代码类似于以下内容:

select id, concat('order', `order`) col,  data value
from tableA
union all
select id, concat('item', item) col, price value
from tableA;

参见 Demo .结果将是:

| ID |    COL | VALUE |
-----------------------
| 1 | order1 | P |
| 1 | order1 | P |
| 1 | order1 | P |
| 1 | item1 | 50 |
| 1 | item2 | 60 |
| 1 | item3 | 70 |

如您所见,这已经采用了多个列 order/dataitem/price 和将其转换为多行。完成后,您可以使用带 CASE 的聚合函数将值转换回列:

select id, 
max(case when col = 'order1' then value end) order1,
max(case when col = 'order2' then value end) order2,
max(case when col = 'order3' then value end) order3,
max(case when col = 'item1' then value end) item1,
max(case when col = 'item2' then value end) item2,
max(case when col = 'item3' then value end) item3
from
(
select id, concat('order', `order`) col, data value
from tableA
union all
select id, concat('item', item) col, price value
from tableA
) d
group by id;

参见 Demo .最后,您需要将上述代码转换为动态准备语句查询:

SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when col = ''',
col,
''' then value end) as `',
col, '`')
) INTO @sql
FROM
(
select concat('order', `order`) col
from tableA
union all
select concat('item', `item`) col
from tableA
)d;

SET @sql = CONCAT('SELECT id, ', @sql, '
from
(
select id, concat(''order'', `order`) col, data value
from tableA
union all
select id, concat(''item'', item) col, price value
from tableA
) d
group by id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

参见 SQL Fiddle with demo .这给出了一个结果:

| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 |  ITEM3 |  ITEM4 |
-------------------------------------------------------------------
| 1 | P | Q | (null) | 50 | 60 | 70 | (null) |
| 2 | P | (null) | S | 50 | 60 | (null) | 80 |

关于Mysql查询在两列的基础上动态将行转列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17964078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com