sql >> Database teknologi >  >> RDS >> Mysql

problemer med mysql pivot tabel

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 |


  1. Hvordan får man den primære nøgle til sidst opdaterede post i MYSQL?

  2. Tæller antallet af forekomster af et tegn i Oracle SQL

  3. Indsæt array-indhold i databasen - php

  4. Fordi du skal kende PowerShell