mysqlselectdynamic行值作为列名,另一列作为值

我有一个遗留的用户信息表(这仍然在积极使用),我不能改变的结构 –

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 

我已经通过各种各样的解决scheme,看看围绕黑客入侵MySQL的数据透视表function,以及类似的,但没有一个似乎匹配这种情况下从同一个表的列中的唯一行值使用variables列名别名。 虽然我几乎没有睡觉,所以他们都开始变得模糊,提前道歉。

最近我可以find将使用预先准备的语句https://stackoverflow.com/a/986088/830171这将首先从名称列中获取所有可能的/唯一的值,并build立使用CASE WHEN ,和/或多个子查询的查询, SELECTJOIN在相同的表查询。

我能想到的替代方法是获取该用户标识的所有行,并在应用程序本身的for循环中处理它们,或尝试将名称限制为有限的数量并使用子SELECT / JOIN 。 然而,第二个选项是不理想的,如果添加一个新的名字,我不得不重新访问这个查询。

请告诉我,我错过了一些明显的东西

与其他一些RDBMS不同的是,MySQL并没有devise支持这种types本地支持(开发人员认为它更适合于应用程序的表示,而不是数据库层)。

如果你绝对必须在MySQL中执行这样的操作,那么build立一个准备好的语句是一条可行的路线 – 尽pipe不是搞乱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_lenvariables的限制(缺省值为1024字节:除非有一些非常长的name值,否则不太可能相关)。