使用T-SQL实现多行转列遇问题,求正确解决方案
T-SQL PIVOT 转换日期列问题排查
测试表结构及数据
CREATE TABLE #test ( ID INT, NAME VARCHAR(10), DATE DATE ) INSERT INTO #TEST VALUES (1, 'Test', '2023-01-01'), (1, 'Test1', '2023-03-01'), (2, 'abc', '2023-01-01'), (2, 'abc1', '2023-03-01')
问题分析
你当前的PIVOT代码存在三个核心错误:
- 聚合目标错误:你需要提取的是
DATE字段值,但代码中聚合的是MAX(ID),无法得到日期结果 - 列名不匹配:
FOR NAME IN ([0], [1])中的列名与表中实际的NAME值(Test、Test1、abc、abc1)完全不符,无法正确映射数据 - 缺失分组依据:最终结果需要按
ID分组,但代码未保留ID列作为分组标识
解决方案
根据你的需求(按ID分组,将同一ID下不同NAME对应的DATE转换为列),提供两种实现方式:
方式一:按实际NAME值作为列名
如果需要保留NAME作为列名,直接将实际NAME值填入FOR NAME IN中:
SELECT ID, [Test] AS Test_Date, [Test1] AS Test1_Date, [abc] AS abc_Date, [abc1] AS abc1_Date FROM ( SELECT ID, NAME, DATE FROM #TEST ) AS SourceTable PIVOT ( MAX(DATE) -- 每个ID+NAME对应唯一DATE,MAX/MIN不影响结果 FOR NAME IN ([Test], [Test1], [abc], [abc1]) ) AS PivotTable;
执行结果:
| ID | Test_Date | Test1_Date | abc_Date | abc1_Date |
|---|---|---|---|---|
| 1 | 2023-01-01 | 2023-03-01 | NULL | NULL |
| 2 | NULL | NULL | 2023-01-01 | 2023-03-01 |
方式二:按同一ID下的日期顺序生成列
如果不需要保留NAME,仅按同一ID下的日期顺序生成列,可先通过ROW_NUMBER()给每个ID下的记录编号,再进行PIVOT:
SELECT ID, [1] AS First_Date, [2] AS Second_Date FROM ( SELECT ID, DATE, -- 按ID分组,按日期排序生成序号 ROW_NUMBER() OVER(PARTITION BY ID ORDER BY DATE) AS Date_Seq FROM #TEST ) AS SourceTable PIVOT ( MAX(DATE) FOR Date_Seq IN ([1], [2]) ) AS PivotTable;
执行结果:
| ID | First_Date | Second_Date |
|---|---|---|
| 1 | 2023-01-01 | 2023-03-01 |
| 2 | 2023-01-01 | 2023-03-01 |
内容的提问来源于stack exchange,提问作者user3311323
相关产品推荐
相关产品推荐

