Når du forsøger at pivotere dynamisk eller ukendt værdi, vil jeg altid foreslå, at du starter med en statisk eller hårdkodet version af forespørgslen først og derefter konverterer den til dynamisk SQL.
MySQL har ikke en PIVOT-funktion, så du skal bruge en aggregeret funktion med et CASE-udtryk for at få resultatet. Den statiske version af koden vil ligne følgende:
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;
Se SQL Fiddle with Demo .
Hvis du nu skal have et ukendt antal keynames
som du vil konvertere til kolonner, så skal du bruge en udarbejdet erklæring
at generere dynamisk SQL. Koden vil ligne:
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;
Se SQL Fiddle with Demo .
Én ting skal du huske på GROUP_CONCAT
funktion til at oprette strengen af kolonner har en standard maks. længde på 1024, så hvis du skal have mange tegn i denne streng, skal du muligvis ændre sessionsværdien for group_concat_max_len
.
Denne forespørgsel vil give et resultat:
| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME | SHAPE | VEGETABLE | FRUIT | ANIMAL |
| 1 | teamA | 1 | processA | circle | carrot | apple | (null) |
| 1 | teamA | 2 | processB | (null) | (null) | (null) | dog |