如何使用SQL PIVOT将查询结果行转列,实现指定格式输出?
解决SQL查询结果行转列问题
现有查询语句如下,返回多行LatinName和对应的CreatedOn日期:
SELECT es.LatinName, es.CreatedOn FROM Salex.ExportFile ef INNER JOIN Salex.ExportFileStep efs ON efs.ExportFileId = ef.Id INNER JOIN GeneralSalex.ExportSubject es ON es.Id = efs.ExportSubjectId WHERE ef.Id = 38
需要将结果转换为一行数据,把LatinName的值作为列名,对应的CreatedOn作为列内容,预期格式如下:
| Packing List | Export Bill Of Lading | ... |
|---|---|---|
| 2021-06-15 16:12:57.6200000 | 2021-07-31 09:30:12.5600000 | ... |
你之前尝试的PIVOT代码存在两个核心问题:
- 对日期类型字段使用
AVG()聚合函数不合适,应该用MAX()或MIN()(因为每个LatinName对应唯一一条记录时,两者结果一致) FOR LatinName IN后的列表写的是[0],[1]这类占位符,不是实际存在的LatinName值
正确的静态PIVOT实现
如果已知所有需要转换的LatinName值,直接写出列名即可:
SELECT [Packing List], [Export Bill Of Lading], -- 继续添加其他需要的LatinName列 FROM ( SELECT es.LatinName, es.CreatedOn FROM Salex.ExportFile ef INNER JOIN Salex.ExportFileStep efs ON efs.ExportFileId = ef.Id INNER JOIN GeneralSalex.ExportSubject es ON es.Id = efs.ExportSubjectId WHERE ef.Id = 38 ) AS SourceTable PIVOT ( MAX(CreatedOn) -- 用MAX/MIN取唯一的日期值 FOR LatinName IN ([Packing List], [Export Bill Of Lading]) -- 替换为实际的LatinName值 ) AS PivotTable;
动态PIVOT实现(适用于LatinName不固定的情况)
如果LatinName的值不确定或经常变化,可以用动态SQL自动生成列列表:
DECLARE @cols NVARCHAR(MAX); DECLARE @query NVARCHAR(MAX); -- 生成所有需要作为列的LatinName值 SELECT @cols = STRING_AGG(QUOTENAME(LatinName), ', ') FROM ( SELECT DISTINCT es.LatinName FROM Salex.ExportFile ef INNER JOIN Salex.ExportFileStep efs ON efs.ExportFileId = ef.Id INNER JOIN GeneralSalex.ExportSubject es ON es.Id = efs.ExportSubjectId WHERE ef.Id = 38 ) AS UniqueNames; -- 拼接动态查询语句 SET @query = N' SELECT ' + @cols + N' FROM ( SELECT es.LatinName, es.CreatedOn FROM Salex.ExportFile ef INNER JOIN Salex.ExportFileStep efs ON efs.ExportFileId = ef.Id INNER JOIN GeneralSalex.ExportSubject es ON es.Id = efs.ExportSubjectId WHERE ef.Id = 38 ) AS SourceTable PIVOT ( MAX(CreatedOn) FOR LatinName IN (' + @cols + N') ) AS PivotTable;'; -- 执行动态查询 EXEC sp_executesql @query;
注:
STRING_AGG适用于SQL Server 2017及以上版本,若使用更低版本,可改用FOR XML PATH方式拼接列名。
内容的提问来源于stack exchange,提问作者Sasan
相关产品推荐
相关产品推荐

