简体   繁体   中英

Pivot table with dynamic columns

I'm having trouble creating a pivot table in MySQL using the following tables:

Teams
-------------
id | name
1  | teamA
2  | teamB

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

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

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

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

The pivot table I am trying to produce should only contain the process details for a given team.

Example

For Team A:

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

For Team B:

teamId | processId | dessert
   2   |     3     | chocolate

Thanks!

Using the query from your previous question you should be able to alter the code to add a WHERE clause that will filter the data for each team:

SET @sql = NULL;
set @team = 'teamA';

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when pd.keyname = ''',
      keyname,
      ''' then tpd.value end) AS ',
      replace(keyname, ' ', '')
    )
  ) INTO @sql
from ProcessDetails
where processId in (select tp.processId
                    from teams t
                    inner join teamprocesses tp
                      on t.id = tp.teamid
                    where t.name = @team);

SET @sql 
    = CONCAT('SELECT t.id teamid, 
                t.name teamname, 
                p.id processid, ', @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
              where t.name = ''', @team, ''' 
              group by t.id, t.name, p.id, p.name;');

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

See SQL Fiddle with Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM