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

使用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;

执行结果:

IDTest_DateTest1_Dateabc_Dateabc1_Date
12023-01-012023-03-01NULLNULL
2NULLNULL2023-01-012023-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;

执行结果:

IDFirst_DateSecond_Date
12023-01-012023-03-01
22023-01-012023-03-01

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:47:45