首页 >数据库 >mysql教程 >如何根据行值透视具有动态列名的 MySQL 表?

如何根据行值透视具有动态列名的 MySQL 表?

Patricia Arquette
Patricia Arquette原创
2025-01-13 19:46:48361浏览

How to Pivot a MySQL Table with Dynamic Column Names from Row Values?

MySQL:将动态行值作为列名

问题:

如何构建一个MySQL查询,将具有可变列名的旧表转换为具有固定列名的表,其中特定列的每个唯一行值都成为列名?

背景:

考虑一个具有以下结构的表:

<code>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</code>

需求:

将表转换为以下格式:

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

MySQL 不支持原生透视操作,因此我们需要找到一种变通方法。

解决方案:

  • GROUP_CONCAT() 函数可用于动态生成创建所需表格式的查询。
  • 第一个查询准备一个字符串,该字符串使用 GROUP_CONCAT() 构建最终查询。
  • 第二个查询使用 PREPAREEXECUTE 来执行动态生成的查询。

查询:

<code class="language-sql">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;</code>

注意事项:

  • GROUP_CONCAT() 结果的长度受 group_concat_max_len 变量(默认为 1024 字节)限制。
  • 或者,可以使用带有 CASE WHEN 或多个子选择/连接的预处理语句,但这需要手动处理唯一列值。

以上是如何根据行值透视具有动态列名的 MySQL 表?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn