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()
构建最终查询。PREPARE
和 EXECUTE
来执行动态生成的查询。查询:
<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中文网其他相关文章!