SQL Server如何按ID将多日期列通过PIVOT/分组转换为行格式
SQL Server 宽表转长表(列转行)实现方案
你需要完成的是固定列宽表按Id维度转长表的操作,这类场景是UNPIVOT算子的典型适用场景,以下提供两种可直接运行的实现方式:
方案1:使用UNPIVOT原生算子(推荐,性能更优)
UNPIVOT是SQL Server专门用于列转行的内置算子,语法简洁执行效率高,适合待转换日期列固定的场景:
注意:你的日期列名包含
/特殊字符,所有列引用必须用方括号[]包裹,否则会触发语法错误
SELECT Id, date, [sum] FROM [db].[exampletable] UNPIVOT ( [sum] -- 存储原日期列对应数值的字段名 FOR date -- 存储原日期列名的字段名 IN ([1/1], [2/1], [3/1]) -- 列出所有需要转换为行的日期列 ) AS converted_table;
方案2:使用UNION ALL拼接(兼容性最强)
如果需要兼容低版本SQL Server,或者需要更灵活的自定义转换逻辑,可以用UNION ALL逐列拼接结果,所有SQL环境都支持该写法:
SELECT Id, '1/1' AS date, [1/1] AS [sum] FROM [db].[exampletable] UNION ALL SELECT Id, '2/1' AS date, [2/1] AS [sum] FROM [db].[exampletable] UNION ALL SELECT Id, '3/1' AS date, [3/1] AS [sum] FROM [db].[exampletable] -- 后续新增日期列时,按上述格式追加UNION ALL块即可 ORDER BY Id, date;
补充说明
- 两种写法返回的结果完全匹配你给出的预期结构,默认会过滤原日期列中值为NULL的行,如果需要保留NULL值可以给UNPIVOT写法加保留逻辑,或在UNION ALL写法中不做过滤
- 如果待转换的日期列数量不固定,可以通过系统表动态读取列名拼接动态SQL,无需每次新增日期列时手动修改代码
内容的提问来源于stack exchange,提问作者Starbucks
相关产品推荐
相关产品推荐

