Quando si tenta di eseguire il pivot di un valore dinamico o sconosciuto, suggerirei sempre di iniziare prima con una versione statica o codificata della query, quindi convertirla in SQL dinamico.
MySQL non ha una funzione PIVOT, quindi dovrai utilizzare una funzione di aggregazione con un'espressione CASE per ottenere il risultato. La versione statica del codice sarà simile alla seguente:
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;
Vedi SQL Fiddle con demo .
Ora, se hai un numero sconosciuto di keynames
che desideri convertire in colonne, dovrai utilizzare un dichiarazione preparata
per generare SQL dinamico. Il codice sarà simile a:
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;
Vedi SQL Fiddle con demo .
Una cosa da tenere a mente GROUP_CONCAT
la funzione per creare la stringa di colonne ha una lunghezza massima predefinita di 1024, quindi se hai molti caratteri in questa stringa potresti dover modificare il valore della sessione per il group_concat_max_len
.
Questa query darà un risultato:
| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME | SHAPE | VEGETABLE | FRUIT | ANIMAL |
| 1 | teamA | 1 | processA | circle | carrot | apple | (null) |
| 1 | teamA | 2 | processB | (null) | (null) | (null) | dog |