我在这里跟随一个问题,使用Mysql查询将行动态转换为列。这工作正常,但我需要根据两列进行转换,
上面链接中提到的查询适用于单列“数据”,但我想适用于“数据”和“价格”两列。
我在这里加了一个例子,
给定一个表A,看起来像
Table A | id|order|data|item|Price| -----+-----+---------------- | 1| 1| P| 1 | 50 | | 1| 1| P| 2 | 60 | | 1| 1| P| 3 | 70 | | 1| 2| Q| 1 | 50 | | 1| 2| Q| 2 | 60 | | 1| 2| Q| 3 | 70 | | 2| 1| P| 1 | 50 | | 2| 1| P| 2 | 60 | | 2| 1| P| 4 | 80 | | 2| 3| S| 1 | 50 | | 2| 3| S| 2 | 60 | | 2| 3| S| 4 | 80 |
我想编写一个如下查询:
Result Table | id|order1|order2|order3|item1|item2|item3|item4| -----+-----+--------------------------------------- | 1| P | Q | | 50 | 60 | 70 | | | 2| P | | S | 50 | 60 | | 80 |
我试图创建两个不同的查询,然后创建一个联接来实现此目的,但这可能不是一个好的解决方案。谁能建议像上面链接中提到的解决方案。
谢谢
如果你有值的已知数量的两个order和item,那么你可以硬编码查询到:
order
item
select id, max(case when `order` = 1 then data end) order1, max(case when `order` = 2 then data end) order2, max(case when `order` = 3 then data end) order3, max(case when item = 1 then price end) item1, max(case when item = 2 then price end) item2, max(case when item = 3 then price end) item3, max(case when item = 4 then price end) item4 from tableA group by id;
参见演示。但是您将要遇到的部分问题是因为您试图转换多列数据。我建议获得最终结果的方法是先取消数据透视。MySQL没有取消透视功能,但是您可以使用UNION ALL将多对列转换为行。要取消透视的代码将类似于以下内容:
select id, concat('order', `order`) col, data value from tableA union all select id, concat('item', item) col, price value from tableA;
参见演示。其结果将是:
| ID | COL | VALUE | ----------------------- | 1 | order1 | P | | 1 | order1 | P | | 1 | order1 | P | | 1 | item1 | 50 | | 1 | item2 | 60 | | 1 | item3 | 70 |
如您所见,这占用了order/ data和item/ 的多个列,price并将其转换为多行。一旦完成,您就可以使用带有CASE的聚合函数将值转换回列:
data
price
select id, max(case when col = 'order1' then value end) order1, max(case when col = 'order2' then value end) order2, max(case when col = 'order3' then value end) order3, max(case when col = 'item1' then value end) item1, max(case when col = 'item2' then value end) item2, max(case when col = 'item3' then value end) item3 from ( select id, concat('order', `order`) col, data value from tableA union all select id, concat('item', item) col, price value from tableA ) d group by id;
参见演示。最后,您需要将以上代码转换为动态的预处理语句查询:
SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'max(case when col = ''', col, ''' then value end) as `', col, '`') ) INTO @sql FROM ( select concat('order', `order`) col from tableA union all select concat('item', `item`) col from tableA )d; SET @sql = CONCAT('SELECT id, ', @sql, ' from ( select id, concat(''order'', `order`) col, data value from tableA union all select id, concat(''item'', item) col, price value from tableA ) d group by id'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
请参阅带有演示的SQL Fiddle。结果如下:
| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 | ITEM3 | ITEM4 | ------------------------------------------------------------------- | 1 | P | Q | (null) | 50 | 60 | 70 | (null) | | 2 | P | (null) | S | 50 | 60 | (null) | 80 |