sql >> Databáze >  >> RDS >> Mysql

Dynamický dotaz v MySQL

Chcete-li získat požadovaný výsledek, budete muset oba odklopit aktuální data ze sloupců do řádků a poté pivot year data z řádků do sloupců.

MySQL nemá funkci PIVOT nebo UNPIVOT, takže budete muset použít UNION ALL dotaz na unpivot a agregační funkci s CASE výraz na pivot.

Pokud máte známý počet hodnot, můžete napevno zakódovat hodnoty podobné tomuto:

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;

Viz SQL Fiddle s ukázkou .

Ale pokud budete mít neznámý počet hodnot, pak budete muset použít připravený příkaz ke generování dynamického SQL. Kód bude podobný následujícímu:

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;

Viz SQL Fiddle s ukázkou . Výsledek pro oba dotazy je:

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



  1. Jak Acosh() funguje v PostgreSQL

  2. vícenásobný dotaz mySQL - vrací chybu mysql_fetch_array

  3. Jaký datový typ by měl být použit pro ukládání telefonních čísel v SQL Server 2005?

  4. ajax datová odpověď vždy 0 v php mysql