MySQL单表列Pivot问题:拼接年月为表头并映射对应值
实现MySQL行转列(Pivot)获取年月作为列的结果
针对你的需求,我们可以通过动态SQL来实现自动生成年月列并完成行转列,下面分两种情况说明:
一、静态年月(已知固定的年月组合)
如果你的年月组合是固定的(比如只有2000-1和2000-2),可以直接写静态SQL,逻辑清晰:
SELECT `key`, MAX(IF(CONCAT(year, '-', month) = '2000-1', value, NULL)) AS `2000-1`, MAX(IF(CONCAT(year, '-', month) = '2000-2', value, NULL)) AS `2000-2` FROM your_table -- 替换成你的实际表名 GROUP BY `key`;
逻辑说明:
- 按
key分组,每个key对应一行结果 - 用
IF判断当前行的年月是否匹配目标列,匹配则取value,否则返回NULL - 用
MAX聚合函数提取每个分组中对应年月的唯一值(因为每个key+年月只会有一条数据,MAX/MIN/SUM都可以达到效果)
二、动态年月(自动适配所有存在的年月组合)
如果你的表中有不确定数量的年月组合,就需要用动态SQL自动生成列,这也是你提到的存储方案的完整实现:
DELIMITER // CREATE PROCEDURE PivotYearMonthData() BEGIN -- 1. 生成所有年月对应的列片段 SET @column_sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(IF(CONCAT(year, '-', month) = ''', CONCAT(year, '-', month), ''', value, NULL)) AS `', CONCAT(year, '-', month), '`' ) ) INTO @column_sql FROM your_table; -- 替换成你的实际表名 -- 2. 拼接完整的查询SQL SET @full_sql = CONCAT( 'SELECT `key`, ', @column_sql, ' FROM your_table GROUP BY `key`' ); -- 3. 执行动态SQL PREPARE stmt FROM @full_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END // DELIMITER ;
使用方法:
调用存储过程即可得到结果:
CALL PivotYearMonthData();
注意事项:
key是MySQL保留字,必须用反引号``包裹,否则会报语法错误- 如果你的实际字段名不是
year/month/value,记得替换成表中对应的字段(比如你提到的combustible_id,需要调整匹配条件) - 如果年月组合非常多,可能需要调整MySQL的
group_concat_max_len参数,避免生成的SQL片段被截断
内容的提问来源于stack exchange,提问作者pmiranda
相关产品推荐
相关产品推荐

