SQL行转列:如何将指定查询结果转换为ID对应多RequestTypeID的宽表
实现SQL行转列(Pivot)的两种方案
针对你需要将查询结果从多行(一个ID对应多个RequestTypeID)转换为单行多列的需求,这里提供两种在SQL Server中常用的实现方式:
方案一:使用PIVOT运算符
PIVOT是SQL Server专门用于行转列的运算符,适合已知需要转换的列数量的场景:
WITH RankedRequests AS ( SELECT temp.ID, request.RequestTypeID, -- 为每个ID下的RequestTypeID按顺序生成序号 ROW_NUMBER() OVER (PARTITION BY temp.ID ORDER BY request.RequestTypeID) AS RequestRank FROM @MyTempTable6 as temp JOIN dbo.FingerMachineUsers as fingeruser ON temp.UserNo = fingeruser.ID JOIN dbo.AppUsers as appuser ON appuser.Id = fingeruser.UserId LEFT JOIN dbo.Requests as request ON request.UserId = fingeruser.UserId -- 过滤掉无RequestTypeID的记录(按需保留或删除) WHERE request.RequestTypeID IS NOT NULL ) SELECT ID, [1] AS RequestTypeID1, [2] AS RequestTypeID2 -- 若存在更多RequestTypeID,可继续添加[3] AS RequestTypeID3等 FROM RankedRequests PIVOT ( MAX(RequestTypeID) -- 聚合函数仅用于占位,每个序号对应唯一值,MAX/MIN均可 FOR RequestRank IN ([1], [2]) ) AS PivotTable;
方案说明
- 先用CTE(
RankedRequests)给每个ID对应的RequestTypeID分配一个唯一序号(RequestRank),序号基于RequestTypeID排序(可根据需求改为按请求时间等其他字段排序)。 - 通过
PIVOT将序号为1、2的RequestTypeID分别转成RequestTypeID1和RequestTypeID2列。
方案二:条件聚合(更灵活的通用方案)
如果需要兼容更低版本的SQL Server,或者希望逻辑更直观,条件聚合是更好的选择:
SELECT ID, -- 提取序号为1的RequestTypeID MAX(CASE WHEN rn = 1 THEN RequestTypeID END) AS RequestTypeID1, -- 提取序号为2的RequestTypeID MAX(CASE WHEN rn = 2 THEN RequestTypeID END) AS RequestTypeID2 -- 如需更多列,继续添加MAX(CASE WHEN rn = N THEN RequestTypeID END) AS RequestTypeIDN FROM ( SELECT temp.ID, request.RequestTypeID, ROW_NUMBER() OVER (PARTITION BY temp.ID ORDER BY request.RequestTypeID) AS rn FROM @MyTempTable6 as temp JOIN dbo.FingerMachineUsers as fingeruser ON temp.UserNo = fingeruser.ID JOIN dbo.AppUsers as appuser ON appuser.Id = fingeruser.UserId LEFT JOIN dbo.Requests as request ON request.UserId = fingeruser.UserId WHERE request.RequestTypeID IS NOT NULL ) AS RankedData GROUP BY ID;
方案说明
- 子查询中同样为每个ID的
RequestTypeID生成序号。 - 使用
CASE语句配合MAX聚合函数,将不同序号的RequestTypeID映射到对应的列中。这种方式无需依赖PIVOT语法,逻辑清晰,修改和扩展都很方便。
注意事项
- 如果允许
RequestTypeID为NULL,可去掉WHERE子句,但结果中对应的列会显示NULL。 - 如果每个ID对应的
RequestTypeID数量超过2个,只需在代码中添加对应序号的列即可(比如rn=3对应RequestTypeID3)。 ORDER BY request.RequestTypeID可以根据业务需求调整排序规则,例如按请求创建时间request.CreateDate排序。
内容的提问来源于stack exchange,提问作者Thien Vu
相关产品推荐
相关产品推荐

