Mysql
 sql >> Baza danych >  >> RDS >> Mysql

problem z tabelą przestawną mysql

Kiedy próbujesz przestawić dynamiczną lub nieznaną wartość, zawsze sugeruję, aby najpierw zacząć od statycznej lub zakodowanej wersji zapytania, a następnie przekonwertować ją na dynamiczny SQL.

MySQL nie posiada funkcji PIVOT, więc aby uzyskać wynik, musisz użyć funkcji agregującej z wyrażeniem CASE. Statyczna wersja kodu będzie podobna do następującej:

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;

Zobacz Skrzypce SQL z wersją demonstracyjną .

Teraz, jeśli będziesz mieć nieznaną liczbę keynames które chcesz przekonwertować na kolumny, musisz użyć przygotowane oświadczenie do generowania dynamicznego SQL. Kod będzie podobny do:

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;

Zobacz Skrzypce SQL z wersją demonstracyjną .

Należy pamiętać o GROUP_CONCAT funkcja do tworzenia ciągu kolumn ma domyślną maksymalną długość 1024, więc jeśli zamierzasz mieć dużo znaków w tym ciągu, być może będziesz musiał zmienić wartość sesji dla group_concat_max_len .

To zapytanie da wynik:

| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME |  SHAPE | VEGETABLE |  FRUIT | ANIMAL |
|      1 |    teamA |         1 |    processA | circle |    carrot |  apple | (null) |
|      1 |    teamA |         2 |    processB | (null) |    (null) | (null) |    dog |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Połączenie MySQL Inner z warunkiem OR?

  2. CakePHP - Efektywne przeszukiwanie 3 tabel przy użyciu funkcji JOIN

  3. Ponowna instalacja Wamp Server bez wymiany istniejącej bazy danych mysql

  4. Wywołanie DATE_FORMAT() w MySQL z Django kończy się niepowodzeniem

  5. Jak wyświetlić obraz z bazy danych za pomocą php