MySQL动态行到列

时间:2016-07-26 14:06:26

标签: mysql pivot transpose group-concat

我正在尝试构建一个将行添加到列的mySQL查询,我获得了最接近的结果,但它不是我需要的,我已经花了很多时间在它上面并且无法弄清楚我缺少的是什么

SET SESSION group_concat_max_len = 1000000;

SET @sql = NULL;

SET @rank=0;

SELECT
  GROUP_CONCAT(
     CONCAT(
        'MAX(CASE WHEN cpus.hardware_id= ''',
         cpus.hardware_id,
         ''' THEN cpus.type END) AS CPU',@rank:=@rank+1
           )
     )INTO @sql
 FROM  
     hardware
 LEFT JOIN  cpus ON hardware.id = cpus.hardware_id;


 SET @sql=CONCAT('SELECT hardware.id, ',@sql,' FROM   
     hardware
     JOIN cpus ON hardware.id = cpus.hardware_id GROUP BY hardware.id');

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

此查询的结果是:

|id|CPU1                                     |CPU2                                 |CPU3                                |
|10|Intel(R) Xeon(R) CPU E5-2407 0 @ 2.20GHz |NULL                                 |NULL                                | 
|11|NULL                                     |Intel(R) Xeon(R) CPU E5530 @ 2.40GHz |Intel(R) Xeon(R) CPU E5530 @ 2.40GHz|

我需要达到的结果是:

|id|CPU1                                     |CPU2                                 |
|10|Intel(R) Xeon(R) CPU E5-2407 0 @ 2.20GHz |NULL                                 |
|11|Intel(R) Xeon(R) CPU E5530 @ 2.40GHz     |Intel(R) Xeon(R) CPU E5530 @ 2.40GHz |

查询需要是动态的,因为每个硬件都有多个CPU。

SQL Fiddle

对此的任何帮助都非常感谢。提前谢谢。

2 个答案:

答案 0 :(得分:0)

我想知道你是否需要动态SQL。如果你想要两列,你可以这样做:

select cpus.hardware_id as id, min(cpus.type) as cpu1,
       (case when min(cpus.type) <> max(cpus.type) then max(cpus.type) end) as cpu2
from cpus
group by cpus.hardware_id;

答案 1 :(得分:0)

我如何讨厌那些数据透视查询问题。我确实相信你在sql中试图解决这个问题时没有任何优势。我的意思是,sql是一种真正结构化数据的语言。特别是,如果您只需要一个id和多个CPU字段:

为什么不抓取

id | number | CPU
---+--------+-----------------------------
 1 |      1 | first cpu description
 1 |      2 | second cpu description
 1 |    ... | ...
 2 |      1 | ... 

我的意思是,无论如何,无论如何,你在软件方面所拥有的代码都可能会循环通过这些cpu,我怀疑。现在在软件方面,只要id是相同的,你就可以收集cpus。

或者你可以在mysql中使用一些没有出现在cpu字段中的分隔符或使用其中一个新的json函数的group_concat。 (是的,我过去常常对这些问题有所了解。而且更简单几乎总是更好。)