Когато се опитвате да завъртите динамична или неизвестна стойност, винаги бих предложил първо да започнете със статична или твърдо кодирана версия на заявката, след което да я конвертирате в динамичен SQL.
MySQL няма функция PIVOT, така че ще трябва да използвате агрегатна функция с CASE израз, за да получите резултата. Статичната версия на кода ще бъде подобна на следното:
изберете t.id teamamid, 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) ) animalfrom teams tinner join teamprocesses tp on t.id =tp.teamidinner join TeamProcessDetails tpd on tp.id =tpd.teamProcessIdinner join процеси p on tp.processid =p.idinner join processdetails pd on p.id =pd.processid и tpd .processDetailsid =pd.idgroup от t.id, t.name, p.id, p.name;
Вижте SQL Fiddle с демонстрация .
Сега, ако ще имате неизвестен брой ключови имена
които искате да конвертирате в колони, тогава ще трябва да използвате подготвен отчет
за генериране на динамичен SQL. Кодът ще бъде подобен на:
SET @sql =NULL;SELECT GROUP_CONCAT(DISTINCT CONCAT( 'max(case when pd.keyname =''', keyname, ''' then tpd.value end) AS ', replace(keyname, ' ', '') ) ) INTO @sqlfrom ProcessDetails;SET @sql =CONCAT('SELECT t.id teamid, t.name teamname, p.id processid, p.name processid, ', @sql, ' from teams t inner присъединяване към teamprocesses tp на t.id =tp.teamid вътрешно присъединяване TeamProcessDetails tpd на tp.id =tpd.teamProcessId вътрешни процеси на присъединяване p на tp.processid =p.id вътрешно присъединяване processdetails pd на p.id =pd.processid и tpd. processDetailsid =pd.id групиране по t.id, t.name, p.id, p.name;');PREPARE stmt FROM @sql;EXECUTE stmt;DEALLOCATE PREPARE stmt;
Вижте SQL Fiddle с демонстрация .
Едно нещо, което трябва да имате предвид GROUP_CONCAT
функцията за създаване на низ от колони има максимална дължина по подразбиране от 1024, така че ако ще имате много знаци в този низ, може да се наложи да промените стойността на сесията за group_concat_max_len
.
Тази заявка ще даде резултат:
<предварителен код>| TEAMID | ИМЕ НА ОТБОРА | ПРОЦЕСИД | ИМЕ НА ПРОЦЕС | ФОРМА | ЗЕЛЕНЧУК | ПЛОДОВЕ | ЖИВОТНО || 1 | екипA | 1 | процесA | кръг | морков | ябълка | (нула) || 1 | екипA | 2 | процесB | (нула) | (нула) | (нула) | куче |