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

Zapytanie dynamiczne w MySQL

Aby uzyskać żądany wynik, musisz oba odkręcić bieżące dane z kolumn do wierszy, a następnie przestaw year dane z wierszy do kolumn.

MySQL nie posiada funkcji PIVOT ani UNPIVOT, więc będziesz musiał użyć UNION ALL zapytanie do unpivot i funkcja agregująca z CASE wyrażenie do obrotu.

Jeśli masz znaną liczbę wartości, możesz na stałe zakodować wartości podobne do tego:

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;

Zobacz SQL Fiddle z wersją demonstracyjną .

Ale jeśli masz mieć nieznaną liczbę wartości, będziesz musiał użyć przygotowanej instrukcji do wygenerowania dynamicznego SQL. Kod będzie podobny do następującego:

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;

Zobacz SQL Fiddle z wersją demonstracyjną . Wynik dla obu zapytań to:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak przekazać wartości oddzielone przecinkami do procedury składowanej w MySql?

  2. O ile szybszy jest MyISAM w porównaniu do InnoDB?

  3. Normy dotyczące dodawania daty/godziny?

  4. Python, Brew i MySQLdb

  5. Django views.py Wersja SQL Join z Multi Table Query