2016-07-26 65 views
1

我想構建一個mySQL查詢,獲得行到列,我取得了最接近的結果,但它不是我所需要的,我已經花了很多時間在上面,無法弄清楚我錯過了什麼。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:[email protected]+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

任何幫助真的讚賞。提前致謝。

回答

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

我需要動態的,因爲我可以有許多行作爲CPU,它取決於每個硬件設備。對於這個示例數據,最大CPU是2,但是如果我有另一個硬件有更多的CPU,查詢應該返回所有這些。 – vandyk

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只是group_concat與一些分隔符不出現在CPU領域或使用其中一個新的JSON函數。 (是的,我也習慣了這些查詢,而且簡單幾乎總是更好。)