T-SQL透视表实现:将多行数据转换为多列
嘿,我来帮你搞定这个行转列的需求!看起来你需要把每个Id对应的多条过期日期和更新日期转换成多列形式,用T-SQL的透视功能就能轻松实现。这里给你两种方案,一种是更灵活的条件聚合(比Pivot更直观,适合处理多个字段),另一种是严格用PIVOT语法的实现,你可以按需选择。
第一步:先给每条记录编序号
首先我们需要给每个Id下的记录按更新时间排序并编上序号,这样才能区分每条数据对应的列位置:
WITH RankedData AS ( SELECT Id, [Expiration Date] AS ExpirationDate, [Expiration Update Date] AS ExpirationUpdateDate, -- 按Id分组,按更新日期排序生成序号(注意转换日期格式) ROW_NUMBER() OVER (PARTITION BY Id ORDER BY CONVERT(DATETIME, [Expiration Update Date])) AS RowNum FROM YourTempView -- 替换成你的视图/临时表名称 )
方案一:条件聚合(推荐,更简洁)
这种方式不需要用到PIVOT关键字,用CASE语句配合聚合函数就能实现行转列,处理多个字段非常方便:
SELECT Id, -- 第一条记录的日期 MAX(CASE WHEN RowNum = 1 THEN ExpirationDate END) AS ExpirationDate_1, MAX(CASE WHEN RowNum = 1 THEN ExpirationUpdateDate END) AS ExpirationUpdateDate_1, -- 第二条记录的日期 MAX(CASE WHEN RowNum = 2 THEN ExpirationDate END) AS ExpirationDate_2, MAX(CASE WHEN RowNum = 2 THEN ExpirationUpdateDate END) AS ExpirationUpdateDate_2, -- 第三条记录的日期 MAX(CASE WHEN RowNum = 3 THEN ExpirationDate END) AS ExpirationDate_3, MAX(CASE WHEN RowNum = 3 THEN ExpirationUpdateDate END) AS ExpirationUpdateDate_3, -- 可以继续添加更多CASE,根据你实际的最大记录数调整 MAX(CASE WHEN RowNum = 4 THEN ExpirationDate END) AS ExpirationDate_4, MAX(CASE WHEN RowNum = 4 THEN ExpirationUpdateDate END) AS ExpirationUpdateDate_4 FROM RankedData GROUP BY Id;
方案二:使用PIVOT语法
如果一定要用PIVOT,因为它一次只能处理一个聚合字段,我们需要先把两个日期字段“拆”成行,再进行透视:
WITH RankedData AS ( SELECT Id, [Expiration Date] AS ExpirationDate, [Expiration Update Date] AS ExpirationUpdateDate, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY CONVERT(DATETIME, [Expiration Update Date])) AS RowNum FROM YourTempView ), UnpivotedData AS ( SELECT Id, -- 生成列名,比如ExpirationDate_1、ExpirationUpdateDate_1 DateType + '_' + CAST(RowNum AS VARCHAR(2)) AS ColumnName, DateValue FROM RankedData -- 把两个日期字段转成行 UNPIVOT ( DateValue FOR DateType IN (ExpirationDate, ExpirationUpdateDate) ) AS Unpvt ) SELECT Id, [ExpirationDate_1], [ExpirationUpdateDate_1], [ExpirationDate_2], [ExpirationUpdateDate_2], [ExpirationDate_3], [ExpirationUpdateDate_3], [ExpirationDate_4], [ExpirationUpdateDate_4] FROM UnpivotedData -- 透视成列 PIVOT ( MAX(DateValue) FOR ColumnName IN ( [ExpirationDate_1], [ExpirationUpdateDate_1], [ExpirationDate_2], [ExpirationUpdateDate_2], [ExpirationDate_3], [ExpirationUpdateDate_3], [ExpirationDate_4], [ExpirationUpdateDate_4] ) ) AS Pvt;
注意事项
- 记得把代码里的
YourTempView替换成你实际的视图或临时表名称; - 你的
Expiration Update Date是字符串格式,排序时一定要用CONVERT(DATETIME, ...)转换成日期类型,否则排序会出错; - 如果每个
Id的记录数不确定,你可以用动态SQL自动生成列,但一般先统计最大记录数,写固定的CASE或Pivot列即可。
内容的提问来源于stack exchange,提问作者slaskwroclaw18
相关产品推荐
相关产品推荐

