许多SQL行合并成一个
我有一个存储过程,它连接一些表来产生一个大的结果集,然后返回到我的应用程序。 应用程序依次循环遍历结果,并结合特定ID上的行,并select每行数据以包含在新对象中。 这也许最容易解释一个例子:
Inspection, Desc, Value 1, Description1, 3 1, Description2, 2 1, Description3, 5
这是代码转换成
Inspection, Description1, Description2, Description3 1, 3, 2, 5
重点是每个检验项目有一行,项目描述为标题,值为检验行和标题的单元格值。 然后将其导出到Excel。
现在的问题是:如何在SQL Server中执行此操作,例如扩展我的SP以返回更less但“更宽”的行,列数更多?
另一个复杂的情况是,一个检查可能有另一个缺乏的行,在这种情况下,解决scheme是添加一个空值或' – '。
PS这是使用Sql Server 2012。
如果您想dynamic执行此操作,而不必知道所有Desc
值是什么,则可以构build您的数据透视查询并使用Exec()
或Execute sp_executesql
DECLARE @Columns NVARCHAR(MAX), @Sql NVARCHAR(MAX) --Build your column headers based on Distinct Desc values SELECT @Columns = COALESCE(@Columns + ',', '') + QUOTENAME([Desc]) FROM (SELECT DISTINCT [Desc] FROM tbl) t ORDER BY [Desc] --Build your pivot query SET @Sql = ' SELECT * FROM tbl PIVOT ( MAX([Value]) FOR [Desc] IN (' + @Columns + ') ) p ' EXEC(@Sql)
如果你想-
对于空值,你需要创build另一个variables来保存你的SQL的Select
部分的转换脚本。
DECLARE @Columns NVARCHAR(MAX), @Sql NVARCHAR(MAX), @ColumnAliases NVARCHAR(MAX) --Build your pivot columns based on Distinct Desc values SELECT @Columns = COALESCE(@Columns + ',', '') + QUOTENAME([Desc]) FROM (SELECT DISTINCT [Desc] FROM tbl) t ORDER BY [Desc] --Build your column headers, replacing NULL with - SELECT @ColumnAliases = COALESCE(@ColumnAliases + ',', '') + 'COALESCE(CONVERT(VARCHAR,' + QUOTENAME([Desc]) + '),''-'') AS ' + QUOTENAME([Desc]) FROM (SELECT DISTINCT [Desc] FROM tbl) t ORDER BY [Desc] --Build your pivot query SET @Sql = ' SELECT Inspection,' + @ColumnAliases + ' FROM tbl PIVOT ( MAX([Value]) FOR [Desc] IN (' + @Columns + ') ) p ' EXEC(@Sql)
如果您使用的是mssql 2005+。 你可以像这样使用一个枢轴:
testing数据
DECLARE @tbl TABLE(Inspection INT, [Desc] VARCHAR(100),Value INT) INSERT INTO @tbl VALUES (1,'Description1', 3), (1,'Description2', 2), (1,'Description3', 5)
询问
SELECT * FROM ( SELECT tbl.Inspection, tbl.[Desc], tbl.Value FROM @tbl AS tbl ) AS tbl PIVOT ( SUM(Value) FOR [Desc] IN ([Description1],[Description2],[Description3]) )AS pvt
结果:
Inspection, Description1, Description2, Description3 1 3 2 5
编辑
正如Juharr在评论中所言:
生成的列名称(表中的值)在构build查询时。 这可能需要另一个初始查询来获取
编辑2
如果你不使用mssql 2005+。 或者想要有和交替的解释。 请参阅以下查询:
SELECT tbl.Inspection, SUM(CASE WHEN [Desc]='Description1' THEN tbl.Value ELSE 0 END) AS Description1, SUM(CASE WHEN [Desc]='Description2' THEN tbl.Value ELSE 0 END) AS Description2, SUM(CASE WHEN [Desc]='Description3' THEN tbl.Value ELSE 0 END) AS Description3 FROM @tbl AS tbl GROUP BY tbl.Inspection
这不需要一个支点,可以在大多数RDMS上使用
你应该使用Sql Server Pivot
。 它将行转换为列。 通过这个例子,你可以有一个最简单的开始。