为了账号安全,请及时绑定邮箱和手机立即绑定

mysql选择动态行值作为列名,另一列作为值

mysql选择动态行值作为列名,另一列作为值

斯蒂芬大帝 2019-08-08 16:56:31
mysql选择动态行值作为列名,另一列作为值我有一个用户信息的遗留表(仍在使用中),我无法改变结构 -id    name       value------------------------------0     timezone   Europe/London0     language   en0     country    450     something  x1     timezone   Europe/Paris1     language   fr1     country    46时区/语言/国家等只是名称的例子,它们可以是变量/除了该列的行之外没有唯一的有限列表我需要一个可以返回的MySQL兼容的SQL查询 -id    timezone       language    country  something---------------------------------------------------0     Europe/London  en          45       x1     Europe/Paris   fr          46我已经查看了关于将数据库中的数据库功能隐藏到MySQL中的stackoverflow的各种答案,类似但是它们似乎都不匹配使用来自同一个表的列中的唯一行值的变量列名别名的情况。虽然我睡得很少,所以他们都开始变得有点模糊,提前道歉。我能找到的最近的将是使用准备好的语句它将首先从名称列中获取所有可能/唯一值并构建一个使用CASE WHEN和/或多个子SELECT或JOIN上的查询相同的表查询。我能想到的替代方法是获取该用户id的所有行并在for循环中在应用程序本身中处理它们,或者尝试将名称限制为有限量并使用sub- SELECTs / JOINs。但是,如果添加新名称,第二个选项并不理想,我必须重新访问此查询。请告诉我,我错过了一些明显的东西
查看完整描述

1 回答

?
慕的地10843

TA贡献1785条经验 获得超8个赞

与其他一些RDBMS不同,MySQL本身不支持这种类型旋转操作(开发人员认为它更适合于应用程序的表示,而不是数据库层)。

如果你绝对必须在MySQL中进行这样的操作,那么构建一个准备好的语句是可行的 - 尽管不是乱用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值,否则此处不太可能相关)。


查看完整回答
反对 回复 2019-08-08
  • 1 回答
  • 0 关注
  • 3285 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信