[英]How to pivot rows to column dynamically in mysql
I'm facing a problem and I think I have to use pivot to solve it which I am not familiar with.我遇到了一个问题,我想我必须使用 pivot 来解决我不熟悉的问题。 I would be very thankful if someone would provide me help.
如果有人能为我提供帮助,我将不胜感激。
The following query results in the following output.以下查询产生以下 output。 This is of course correct.
这当然是正确的。
SELECT tm.team_id AS team, pp.user_name AS name, tm.rank AS rank
FROM teams_members AS tm
LEFT JOIN players_profiles AS pp
ON pp.uid=tm.user_id
WHERE tm.team_id = 1 OR tm.team_id = 2
ORDER BY tm.team_id, tm.rank
team![]() |
name![]() |
rank![]() |
---|---|---|
1 ![]() |
1Player1 ![]() |
1 ![]() |
1 ![]() |
1Player2 ![]() |
2 ![]() |
1 ![]() |
1Player3 ![]() |
2 ![]() |
1 ![]() |
1Player4 ![]() |
2 ![]() |
1 ![]() |
1Player5 ![]() |
3 ![]() |
1 ![]() |
1Player6 ![]() |
4 ![]() |
1 ![]() |
1Player7 ![]() |
5 ![]() |
2 ![]() |
2Player1 ![]() |
1 ![]() |
2 ![]() |
2Player2 ![]() |
2 ![]() |
2 ![]() |
2Player3 ![]() |
2 ![]() |
2 ![]() |
2Player4 ![]() |
2 ![]() |
I want the table to look like this though.我希望桌子看起来像这样。 How do I have to adapt the query?
我如何调整查询? It is possible, that rank 2 can hold an unlimited amount of players.
有可能,等级2可以容纳无限数量的玩家。 Rank 1,3,4 and 5 are set to a limit of 1.
等级 1、3、4 和 5 设置为限制为 1。
team![]() |
1 ![]() |
2 ![]() |
2 ![]() |
2 ![]() |
3 ![]() |
4 ![]() |
5 ![]() |
---|---|---|---|---|---|---|---|
1 ![]() |
1Player1 ![]() |
1Player2 ![]() |
1Player3 ![]() |
1Player4 ![]() |
1Player5 ![]() |
1Player6 ![]() |
1Player7 ![]() |
2 ![]() |
2Player1 ![]() |
2Player2 ![]() |
2Player3 ![]() |
2Player4 ![]() |
|||
3 ![]() |
3Player1 ![]() |
3Player2 ![]() |
3Player3 ![]() |
3Player4 ![]() |
3Player5 ![]() |
||
4 ![]() |
4Player1 ![]() |
4Player2 ![]() |
4Player3 ![]() |
3Player4 ![]() |
I appreciate any help.我很感激任何帮助。 Thanks a lot!
非常感谢!
To give you another example: DBFIDDLE再举一个例子: DBFIDDLE
DROP TABLE IF EXISTS testPivot ;
CREATE TABLE testPivot(i int, name varchar(20), k int);
INSERT INTO testPivot VALUES
(1,'1Player1',1),
(1,'1Player2',2),
(1,'1Player3',2),
(1,'1Player4',2),
(1,'1Player5',3),
(1,'1Player6',4),
(1,'1Player7',5),
(2,'2Player1',1),
(2,'2Player2',2),
(2,'2Player3',2),
(2,'2Player4',2);
SELECT
i as team,
max(case when right(name,1)='1' then name else '' end) as '1',
max(case when right(name,1)='2' then name else '' end) as '2',
max(case when right(name,1)='3' then name else '' end) as '3',
max(case when right(name,1)='4' then name else '' end) as '4',
max(case when right(name,1)='5' then name else '' end) as '5',
max(case when right(name,1)='6' then name else '' end) as '6',
max(case when right(name,1)='7' then name else '' end) as '7'
FROM testPivot
GROUP BY i;
output: output:
team![]() |
1 ![]() |
2 ![]() |
3 ![]() |
4 ![]() |
5 ![]() |
6 ![]() |
7 ![]() |
---|---|---|---|---|---|---|---|
1 ![]() |
1Player1 ![]() |
1Player2 ![]() |
1Player3 ![]() |
1Player4 ![]() |
1Player5 ![]() |
1Player6 ![]() |
1Player7 ![]() |
2 ![]() |
2Player1 ![]() |
2Player2 ![]() |
2Player3 ![]() |
2Player4 ![]() |
EDIT: The get group 2 in 1 column (I only applied the change for rank==2), use:编辑:在 1 列中获取第 2 组(我只应用了 rank==2 的更改),使用:
SELECT
i as team,
max(case when right(name,1)='1' then name else '' end) as '1',
regexp_replace(regexp_replace(regexp_replace(group_concat(case when k=2 then name else '' end),'[,]+',','),'^,',''),',$','') as '2',
-- max(case when right(name,1)='2' then name else '' end) as '2',
max(case when right(name,1)='3' then name else '' end) as '3',
max(case when right(name,1)='4' then name else '' end) as '4',
max(case when right(name,1)='5' then name else '' end) as '5',
max(case when right(name,1)='6' then name else '' end) as '6',
max(case when right(name,1)='7' then name else '' end) as '7'
FROM testPivot
GROUP BY i;
team![]() |
1 ![]() |
2 ![]() |
3 ![]() |
4 ![]() |
5 ![]() |
6 ![]() |
7 ![]() |
---|---|---|---|---|---|---|---|
1 ![]() |
1Player1 ![]() |
1Player2,1Player3,1Player4 ![]() |
1Player3 ![]() |
1Player4 ![]() |
1Player5 ![]() |
1Player6 ![]() |
1Player7 ![]() |
2 ![]() |
2Player1 ![]() |
2Player2,2Player3,2Player4 ![]() |
2Player3 ![]() |
2Player4 ![]() |
MySQL does not support PIVOT relational operator. MySQL 不支持 PIVOT 关系运算符。 But surely there is way to pivot data in MySQL.
但肯定有办法在 MySQL 中获取 pivot 数据。 The challenge in your data was non uniqueness of pivot columns.
您数据中的挑战是 pivot 列的非唯一性。 There would be multiple columns with name "2" in your output.
output 中会有多个名称为“2”的列。
So I have created uniqueness by concatenating team last three later of name field.所以我通过连接名称字段的后三个团队来创建唯一性。 I am sharing here both static and dynamic pivoting for your data.
我在这里分享 static 和数据的动态旋转。 In dynamic pivot it would not matter if you have three players or ten it will deliver your data in your required format.
在动态 pivot 中,无论您有 3 个还是 10 个播放器,它都会以您所需的格式提供您的数据。 But if your team list is fixed along with player list then you can go for static pivot since it will be faster.
但是,如果您的团队列表与玩家列表一起固定,那么您可以 go for static pivot 因为它会更快。
In dynamic pivot I have created your data as table t
.在动态 pivot 中,我已将您的数据创建为表
t
。 You can put your entire select query in place of t
.您可以将整个 select 查询代替
t
。
Schema:架构:
create table t (team int, name varchar(50) ,rank int);
insert into t values(1, '1Player1', 1);
insert into t values(1, '1Player2', 2);
insert into t values(1, '1Player3', 2);
insert into t values(1, '1Player4', 2);
insert into t values(1, '1Player5', 3);
insert into t values(1, '1Player6', 4);
insert into t values(1, '1Player7', 5);
insert into t values(2, '2Player1', 1);
insert into t values(2, '2Player2', 2);
insert into t values(2, '2Player3', 2);
insert into t values(2, '2Player4', 2);
Query#1 (static pivot)查询#1(静态枢轴)
SELECT team, MAX(IF(concat(rank,right(name,3)) = '1er1', concat(rank,name), NULL)) AS "1",
MAX(IF(concat(rank,right(name,3)) = '2er2', concat(rank,name), NULL)) AS "2",
MAX(IF(concat(rank,right(name,3)) = '2er3', concat(rank,name), NULL)) AS "2",
MAX(IF(concat(rank,right(name,3)) = '2er4', concat(rank,name), NULL)) AS "2",
MAX(IF(concat(rank,right(name,3)) = '3er5', concat(rank,name), NULL)) AS "3",
MAX(IF(concat(rank,right(name,3)) = '4er6', concat(rank,name), NULL)) AS "4",
MAX(IF(concat(rank,right(name,3)) = '5er7', concat(rank,name), NULL)) AS "5"
FROM (SELECT tm.team_id AS team, pp.user_name AS name, tm.rank AS rank
FROM teams_members AS tm
LEFT JOIN players_profiles AS pp
ON pp.uid=tm.user_id
WHERE tm.team_id = 1 OR tm.team_id = 2
ORDER BY tm.team_id, tm.rank)t
GROUP BY team
Query#2 (dynamic pivot)查询#2(动态枢轴)
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(concat(rank,right(name,3)) = ''',
concat(rank,right(name,3)),
''', concat(rank,name), NULL)) AS ',
concat('"',rank,'"')
)
) INTO @sql
FROM t;
SET @sql = CONCAT('SELECT team
, ', @sql, '
FROM t
GROUP BY team');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Output: Output:
team![]() |
1 ![]() |
2 ![]() |
2 ![]() |
2 ![]() |
3 ![]() |
4 ![]() |
5 ![]() |
---|---|---|---|---|---|---|---|
1 ![]() |
11Player1 ![]() |
21Player2 ![]() |
21Player3 ![]() |
21Player4 ![]() |
31Player5 ![]() |
41Player6 ![]() |
51Player7 ![]() |
2 ![]() |
12Player1 ![]() |
22Player2 ![]() |
22Player3 ![]() |
22Player4 ![]() |
null ![]() |
null ![]() |
null ![]() |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.