Cuando intenta pivotar un valor dinámico o desconocido, siempre le sugiero que primero comience con una versión estática o codificada de la consulta y luego la convierta a SQL dinámico.
MySQL no tiene una función PIVOT, por lo que deberá usar una función agregada con una expresión CASE para obtener el resultado. La versión estática del código será similar a la siguiente:
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;
Consulte SQL Fiddle con demostración .
Ahora, si va a tener un número desconocido de keynames
que desea convertir en columnas, deberá usar un declaración preparada
para generar SQL dinámico. El código será similar 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;
Consulte SQL Fiddle con demostración .
Una cosa a tener en cuenta es el GROUP_CONCAT
La función para crear la cadena de columnas tiene una longitud máxima predeterminada de 1024, por lo que si va a tener muchos caracteres en esta cadena, es posible que deba modificar el valor de la sesión para group_concat_max_len
.
Esta consulta dará un resultado:
| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME | SHAPE | VEGETABLE | FRUIT | ANIMAL |
| 1 | teamA | 1 | processA | circle | carrot | apple | (null) |
| 1 | teamA | 2 | processB | (null) | (null) | (null) | dog |