gpt4 book ai didi

mysql - mysql数据透视表的问题

转载 作者:行者123 更新时间:2023-11-29 02:27:38 25 4
gpt4 key购买 nike

我在使用下表在 MySQL 中创建数据透视表时遇到问题:

Teams
-------------
id | name
1 | teamA

Processes
-------------
id | name
1 | processA
2 | processB

ProcessDetails
---------------
id | processId | keyName
1 | 1 | shape
2 | 1 | vegetable
3 | 1 | fruit
4 | 2 | animal

TeamProcesses
-----------------
id | teamId | processId
5 | 1 | 1
6 | 1 | 2

TeamProcessDetails
--------------------
id | teamProcessId | proccessDetailsId | value
1 | 5 | 1 | circle
2 | 5 | 2 | carrot
3 | 5 | 3 | apple
4 | 6 | 4 | dog

我要生成的数据透视表是这个:

Pivot Table
------------
teamId | processId | shape | vegetable | fruit | animal
1 | 1 | circle | carrot | apple | NULL
1 | 2 | NULL | NULL | NULL | dog

需要注意的是key的个数是动态的所以我觉得需要用prepared statement的方式。此外,进程没有相同的键,因此它们应该只有属于该进程的键的值。

谢谢!

最佳答案

当您尝试转换动态值或未知值时,我总是建议您首先从查询的静态或硬编码版本开始,然后将其转换为动态 SQL。

MySQL 没有 PIVOT 函数,因此您需要使用带有 CASE 表达式的聚合函数来获取结果。代码的静态版本将类似于以下内容:

select t.id teamid, 
t.name teamname,
p.id processid,
p.name processname,
max(case when pd.keyname = 'shape' then tpd.value end) shape,
max(case when pd.keyname = 'vegetable' then tpd.value end) vegetable,
max(case when pd.keyname = 'fruit' then tpd.value end) fruit,
max(case when pd.keyname = 'animal' then tpd.value end) animal
from teams t
inner join teamprocesses tp
on t.id = tp.teamid
inner join TeamProcessDetails tpd
on tp.id = tpd.teamProcessId
inner join processes p
on tp.processid = p.id
inner join processdetails pd
on p.id = pd.processid
and tpd.processDetailsid = pd.id
group by t.id, t.name, p.id, p.name;

参见 SQL Fiddle with Demo .

现在,如果您要拥有未知数量的 keynames你想转换成列,那么你需要使用 prepared statement生成动态 SQL。代码将类似于:

SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when pd.keyname = ''',
keyname,
''' then tpd.value end) AS ',
replace(keyname, ' ', '')
)
) INTO @sql
from ProcessDetails;

SET @sql
= CONCAT('SELECT t.id teamid,
t.name teamname,
p.id processid,
p.name processname, ', @sql, '
from teams t
inner join teamprocesses tp
on t.id = tp.teamid
inner join TeamProcessDetails tpd
on tp.id = tpd.teamProcessId
inner join processes p
on tp.processid = p.id
inner join processdetails pd
on p.id = pd.processid
and tpd.processDetailsid = pd.id
group by t.id, t.name, p.id, p.name;');

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

参见 SQL Fiddle with Demo .

要记住的一件事 GROUP_CONCAT 创建列字符串的函数的默认最大长度为 1024,因此如果您要在此字符串中包含很多字符,则可能必须更改 group_concat_max_len 的 session 值。 .

这个查询会给出一个结果:

| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME |  SHAPE | VEGETABLE |  FRUIT | ANIMAL |
| 1 | teamA | 1 | processA | circle | carrot | apple | (null) |
| 1 | teamA | 2 | processB | (null) | (null) | (null) | dog |

关于mysql - mysql数据透视表的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18729532/

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