sql >> Databasteknik >  >> RDS >> Mysql

Dynamisk fråga i MySQL

För att få det resultat du vill ha måste du båda avpivotera aktuell data från kolumner till rader och vrid sedan year data från rader till kolumner.

MySQL har ingen PIVOT- eller UNPIVOT-funktion, så du måste använda en UNION ALL fråga för att avpivot och en aggregerad funktion med en CASE uttryck att pivotera.

Om du har ett känt antal värden kan du hårdkoda värden liknande detta:

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;

Se SQL-fiol med demo .

Men om du ska ha ett okänt antal värden, måste du använda en förberedd sats för att generera dynamisk SQL. Koden kommer att likna följande:

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;

Se SQL-fiol med demo . Resultatet för båda frågorna är:

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



  1. decimal(s,p) eller tal(s,p)?

  2. Hur man skapar flera en till en

  3. xampp MySQL startar inte

  4. Vad är socket-deklarationen för, i Ruby on Rails database.yml?