如何使用UnPivot实现列转行并替换月份列名
解决UNPIVOT后月份代码转名称的问题
你已经把核心的列转行操作(UNPIVOT)做对了!要把M01这类月份代码转换成对应的英文名称,只需要在查询中添加一层转换逻辑即可,这里给你几个实用的方案:
方案1:使用CASE表达式(简单直接,兼容性强)
这是最直观的方法,直接通过CASE语句把每个月份代码映射到对应的名称,适合固定的月份映射场景,几乎兼容所有SQL版本:
SELECT CASE Months WHEN 'M01' THEN 'January' WHEN 'M02' THEN 'February' WHEN 'M03' THEN 'March' WHEN 'M04' THEN 'April' WHEN 'M05' THEN 'May' WHEN 'M06' THEN 'June' WHEN 'M07' THEN 'July' WHEN 'M08' THEN 'August' WHEN 'M09' THEN 'September' WHEN 'M10' THEN 'October' WHEN 'M11' THEN 'November' WHEN 'M12' THEN 'December' END AS [Month], [Count] FROM [TableName] UNPIVOT( [Count] FOR Months IN ([M01], [M02], [M03], [M04], [M05], [M06], [M07], [M08], [M09], [M10], [M11], [M12]) ) AS unpiv
方案2:用日期函数动态生成(简洁高效,适合SQL Server 2012+)
如果你用的是SQL Server 2012及以上版本,可以通过提取月份代码中的数字部分,拼接成日期后再转成月份名称,不用写冗长的CASE语句:
SELECT DATENAME(MONTH, DATEFROMPARSE('2020-' + SUBSTRING(Months, 2, 2) + '-01', 'yyyy-MM-dd')) AS [Month], [Count] FROM [TableName] UNPIVOT( [Count] FOR Months IN ([M01], [M02], [M03], [M04], [M05], [M06], [M07], [M08], [M09], [M10], [M11], [M12]) ) AS unpiv
注:如果是其他数据库(比如MySQL),可以用类似的函数替代,比如
MONTHNAME(STR_TO_DATE(SUBSTRING(Months,2,2), '%m'))
方案3:使用映射表关联(灵活可扩展,适合复杂场景)
如果后续可能需要修改月份名称、添加多语言支持或者扩展其他映射规则,建议创建一个月份映射表,通过关联查询实现转换:
首先创建映射表:
CREATE TABLE MonthMapping ( MonthCode VARCHAR(3) PRIMARY KEY, MonthName VARCHAR(20) NOT NULL ); INSERT INTO MonthMapping VALUES ('M01', 'January'), ('M02', 'February'), ('M03', 'March'), ('M04', 'April'), ('M05', 'May'), ('M06', 'June'), ('M07', 'July'), ('M08', 'August'), ('M09', 'September'), ('M10', 'October'), ('M11', 'November'), ('M12', 'December');
然后关联查询:
SELECT mm.MonthName AS [Month], unpiv.[Count] FROM [TableName] UNPIVOT( [Count] FOR Months IN ([M01], [M02], [M03], [M04], [M05], [M06], [M07], [M08], [M09], [M10], [M11], [M12]) ) AS unpiv JOIN MonthMapping mm ON unpiv.Months = mm.MonthCode;
这个方案的优势在于,后续修改映射规则只需要更新MonthMapping表,不需要改动主查询,维护起来更方便。
内容的提问来源于stack exchange,提问作者Zeeshan Adil
相关产品推荐
相关产品推荐

