如何动态地将行转换为列,反之亦然

时间:2012-10-23 07:10:20

标签: mysql sql pivot dynamic-data

  

可能重复:
  Select MYSQL rows but rows into columns and column into rows

如何显示:

╔══════╦════╦════╗
║ Code ║ A  ║ B  ║
╠══════╬════╬════╣
║ xxxx ║ 50 ║ 63 ║
║ yyyy ║ 38 ║ 68 ║
║ .... ║ .. ║ .. ║
╚══════╩════╩════╝

喜欢这个:

╔══════╦══════╦══════╦═════╗
║ Code ║ xxxx ║ yyyy ║ ... ║
╠══════╬══════╬══════╬═════╣
║ A    ║   50 ║   63 ║ ... ║
║ B    ║   38 ║   68 ║ ... ║
╚══════╩══════╩══════╩═════╝

因为它可能有一些“代码”,如xxxx,yyyy,zzzz,...
因此,我需要动态显示所有“代码”而不进行硬编码。

1 个答案:

答案 0 :(得分:1)

不幸的是,MySQL没有UNPIVOTPIVOT函数,但可以使用UNION ALL UNPIVOTCASE的聚合函数复制它们。 PIVOT的语句。如果您知道要转换的值,那么您可以硬编码,类似于以下内容:

select col code,
  sum(case when code = 'xxxx' then value end) xxxx,
  sum(case when code = 'xxxx' then value end) yyyy
from
(
  select code, A value, 'A' col
  from table1
  union all
  select code, B value, 'B' col
  from table1
) x
group by col;

请参阅SQL Fiddle with Demo

但是您声明您将拥有未知数量的code值。如果是这种情况,那么您可以使用准备好的语句来pivot数据:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(case when code = ''',
      code,
      ''' then value end) AS ',
      code
    )
  ) INTO @sql
FROM Table1;

SET @sql = CONCAT('SELECT col as code, ', @sql, ' 
                  FROM
                  (
                    select code, A value, ''A'' col
                    from table1
                    union all
                    select code, B value, ''B'' col
                    from table1
                  ) x
                  GROUP BY col');

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

SQL Fiddle with Demo

两者产生相同的结果:

| CODE | XXXX | YYYY |
----------------------
|    A |   50 |   38 |
|    B |   63 |   68 |