2012-06-07 143 views
21

我有用戶信息的遺留表(即仍處於活躍使用),我不能改變的結構 -MySQL的選擇動態行值作爲列名,另一列值

id name  value 
------------------------------ 
0  timezone Europe/London 
0  language en 
0  country 45 
0  something x 
1  timezone Europe/Paris 
1  language fr 
1  country 46 

時區/語言/國家等只是名字的例子,它們可以是可變的/沒有比其他唯一沒有有限名單上那一列的行

我需要一個MySQL兼容SQL查詢將返回 -

id timezone  language country something 
--------------------------------------------------- 
0  Europe/London en   45  x 
1  Europe/Paris fr   46 

我已經通過各種答案看着計算器圍繞MySQL的黑客透視表功能,和類似的,但他們都不符合此情況下,利用獨特的行值從同一個表的列變量列名的別名。雖然我幾乎沒有睡眠,所以他們都開始變得模糊,提前道歉。

最近我能找到的辦法是使用準備好的語句https://stackoverflow.com/a/986088/830171這將首先從名字列得到所有可能的/獨特的價值和構建一個使用CASE WHEN查詢,和/或多個子SELECTJOIN在同一個表的查詢。

我能想到的替代將得到所有行該用戶ID和一個for循環,或試圖限制名稱量有限,使用亞SELECT S程序中他們在應用程序本身/ JOIN s。然而,如果添加一個新名字,那麼第二個選項並不理想,我不得不重新訪問這個查詢。

請告訴我,我已經錯過了一些明顯的

+0

你真的需要這在'sql'表達或將後處理與您選擇的編程語言就足夠了?如果您需要加入反對您的非破壞性數據,那麼視圖/ proc可能就是訣竅。 – bluevector

+0

現在,我會在應用程序級別保持一團糟 - 我將獲取該用戶標識的所有行並循環將數據放入關聯數組中。我只是想檢查這是唯一的好選擇。使用SQL方法進行遷移和一次性報告仍然非常方便。 – gingerCodeNinja

回答

39

不像其他一些RDBMS MySQL沒有通過設計樞這種的操作原生支持(開發商覺得這是更適合演示,而比您的應用程序的數據庫層)。

如果你絕對必須MySQL內perfom這樣的操作,建立一個準備語句是去—雖然,而不是CASE亂搞的樣子,我可能只是使用MySQL的GROUP_CONCAT()功能:

SELECT CONCAT(
    'SELECT `table`.id', GROUP_CONCAT(' 
    , `t_', REPLACE(name, '`', '``'), '`.value 
     AS `', REPLACE(name, '`', '``'), '`' 
    SEPARATOR ''), 
' FROM `table` ', GROUP_CONCAT(' 
    LEFT JOIN `table` AS `t_', REPLACE(name, '`', '``'), '` 
      ON `table`.id = `t_', REPLACE(name, '`', '``'), '`.id 
      AND `t_', REPLACE(name, '`', '``'), '`.name = ', QUOTE(name) 
    SEPARATOR ''), 
' GROUP BY `table`.id' 
) INTO @qry FROM (SELECT DISTINCT name FROM `table`) t; 

PREPARE stmt FROM @qry; 
EXECUTE stmt; 

見它在sqlfiddle

請注意,GROUP_CONCAT()的結果受group_concat_max_len變量的限制(缺省爲1024字節:除非有一些非常長的name值,否則這裏不太可能相關)。

+4

哇 - 感謝您爲編寫和測試解決方案所付出的全部努力。非常感激。我一直想知道如何進行這種查詢,而且看起來像我想象的那樣複雜。現在,我會在應用程序級別保持這種混亂狀態,但這個查詢仍然非常方便用於報告和遷移。謝謝。 – gingerCodeNinja

+0

我有一個非常相似的情況,並使用你的優秀示例,我可以看到正確的結果。但我需要將結果存儲在表中,因爲我想從中生成圖表。是否有可能將旋轉結果存儲到表中?另外,是否有可能在Php上面執行?我的源表是用戶,日期,性能和數據透視表用戶爲行,日期爲列,性能爲單元格值。 – Sri

+0

已將我的示例表放在sqlfiddle上(請參閱http://sqlfiddle.com/#!2/06be4/1) – Sri