You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SSMS中使用T-SQL将单列日期按工单转换为多列日期

T-SQL 动态行转列实现方案

你描述的需求实际是**动态PIVOT(行转列)**操作(UNPIVOT是列转行,和你的目标方向相反),不需要提前预知每个工单的更新日期数量,也不会破坏你已经用row_number()排好的顺序,具体实现逻辑和代码如下:

实现逻辑

  • 因为你已经通过row_number() over(partition by ticket ...)给每个工单下的更新日期生成了连续且唯一的序号rownum,直接基于这个序号做动态行转列即可
  • 由于每个(ticket, rownum)组合只对应唯一一条日期记录,PIVOT语法要求的聚合函数仅做语法占位,不会实际触发多值聚合计算
  • 动态拼接列名时按rownum升序排列,保证最终输出的Dt1、Dt2...列顺序和你预设的排序完全一致,列总数自动适配全表工单的最大更新次数

可直接运行的代码

首先假设你的原表名为ticket_update,你可以替换成自己的实际表名:

-- 若需要复现样例数据,可先执行以下建表插数语句
-- CREATE TABLE ticket_update (
--     rownum INT,
--     ticket INT,
--     updated DATE
-- )
-- INSERT INTO ticket_update VALUES
-- (1,1,'2022-01-01'),
-- (2,1,'2022-01-03'),
-- (1,2,'2022-01-27'),
-- (1,3,'2022-03-01'),
-- (2,3,'2022-04-02'),
-- (3,3,'2022-05-03'), -- 原样例此处笔误写为3/1/2022,对应目标表第三列5/3/2022
-- (1,4,'2022-07-11')

DECLARE @cols NVARCHAR(MAX), @pivot_cols NVARCHAR(MAX), @sql NVARCHAR(MAX)

-- 自动生成所有需要的日期列,适配任意数量的更新次数
-- SQL Server 2017及以上版本用STRING_AGG拼接
SELECT 
    @cols = STRING_AGG('[' + CAST(rownum AS VARCHAR(10)) + '] AS Dt' + CAST(rownum AS VARCHAR(10)), ',')
    WITHIN GROUP (ORDER BY rownum),
    @pivot_cols = STRING_AGG('[' + CAST(rownum AS VARCHAR(10)) + ']', ',')
    WITHIN GROUP (ORDER BY rownum)
FROM (SELECT DISTINCT rownum FROM ticket_update) t

-- 低版本SQL Server(2016及以下)用下面的FOR XML PATH逻辑替换上面的列拼接即可
-- SELECT 
--     @cols = STUFF((SELECT ',[' + CAST(rownum AS VARCHAR(10)) + '] AS Dt' + CAST(rownum AS VARCHAR(10)) FROM (SELECT DISTINCT rownum FROM ticket_update) t ORDER BY rownum FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,1,''),
--     @pivot_cols = STUFF((SELECT ',[' + CAST(rownum AS VARCHAR(10)) + ']' FROM (SELECT DISTINCT rownum FROM ticket_update) t ORDER BY rownum FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'')

-- 拼接最终查询语句
SET @sql = '
SELECT ticket, ' + @cols + '
FROM ticket_update
PIVOT (
    MAX(updated) -- 仅为PIVOT语法要求占位,无实际聚合计算
    FOR rownum IN (' + @pivot_cols + ')
) p
ORDER BY ticket'

-- 执行查询得到结果
EXEC sp_executesql @sql

效果说明

  • 执行后输出的列数会自动匹配全表工单的最大更新次数,不需要手动修改代码
  • 每个工单下的日期严格按照你预先用row_number()生成的顺序横向排列,更新日期不足的工单对应Dt列会返回空值,和你给出的目标表结构完全一致
  • 因为没有额外的分组、排序逻辑,查询性能和直接查询原表基本一致

内容的提问来源于stack exchange,提问作者Compass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:01:20