sql >> Database >  >> RDS >> Mysql

Dynamische query in MySQL

Om het gewenste resultaat te krijgen, moet u beide de draai opheffen de huidige gegevens van kolommen naar rijen en draai vervolgens het year gegevens van rijen naar kolommen.

MySQL heeft geen PIVOT- of UNPIVOT-functie, dus u moet een UNION ALL gebruiken query om de draaiing ongedaan te maken en een aggregatiefunctie met een CASE uitdrukking om te draaien.

Als u een bekend aantal waarden heeft, kunt u waarden als volgt hardcoderen:

select locid,
  event,
  max(case when year = 2011 then value end) `2011`,
  max(case when year = 2012 then value end) `2012`
from
(
  select LocId, Year, 'Birth' event, Birth value
  from yt
  union all
  select LocId, Year, 'Death' event, Death value
  from yt
  union all
  select LocId, Year, 'Abc' event, Abc value
  from yt
) d
group by locid, event;

Zie SQL Fiddle met demo .

Maar als u een onbekend aantal waarden wilt hebben, moet u een voorbereide instructie gebruiken om dynamische SQL te genereren. De code ziet er ongeveer als volgt uit:

SET @sql = NULL;
SET @sqlUnpiv = NULL;
SET @sqlPiv = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'select locid, year, ''',
      c.column_name,
      ''' as event, ',
      c.column_name,
      ' as value 
      from yt '
    ) SEPARATOR ' UNION ALL '
  ) INTO @sqlUnpiv
FROM information_schema.columns c
where c.table_name = 'yt'
  and c.column_name not in ('LocId', 'Year')
order by c.ordinal_position;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(CASE WHEN year = ',
      year,
      ' THEN value else null END) AS `',
      year, '`'
    )
  ) INTO @sqlPiv
FROM yt;

SET @sql 
  = CONCAT('SELECT locid,
              event, ', @sqlPiv, ' 
            from 
            ( ',  @sqlUnpiv, ' ) d
            group by locid, event');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Zie SQL Fiddle met demo . Het resultaat voor beide zoekopdrachten is:

| LOCID | EVENT | 2011 | 2012 |
-------------------------------
|     1 |   Abc |   10 |   20 |
|     1 | Birth |  100 |   98 |
|     1 | Death |   60 |   70 |



  1. Problemen met MySQL C#-tekstcodering

  2. Een query verbeteren met veel inner joins naar wp_postmeta, een sleutel/waarde-tabel

  3. Wat is er mis met deze PL/SQL? Bindvariabele * is NIET VERKLAARD

  4. Grootte van MySQL-schema