C# 将多个SQL行合并为一个
我有一个存储过程,它连接许多表以生成一个大的结果集,然后返回到我的应用程序。应用程序依次循环遍历结果并合并特定ID上的行,并选择每行数据以包含在新对象中。这也许是用一个例子最容易解释的:C# 将多个SQL行合并为一个,c#,sql,sql-server,excel,sql-server-2012,C#,Sql,Sql Server,Excel,Sql Server 2012,我有一个存储过程,它连接许多表以生成一个大的结果集,然后返回到我的应用程序。应用程序依次循环遍历结果并合并特定ID上的行,并选择每行数据以包含在新对象中。这也许是用一个例子最容易解释的: Inspection, Desc, Value 1, Description1, 3 1, Description2, 2 1, Description3, 5 这是在代码中转换成的 Inspection, Descripti
Inspection, Desc, Value
1, Description1, 3
1, Description2, 2
1, Description3, 5
这是在代码中转换成的
Inspection, Description1, Description2, Description3
1, 3, 2, 5
其要点是,每个检验项目有一行,项目描述作为标题,值作为检验行和标题的单元格值。然后将其导出到Excel
问题是:如何在SQL Server中实现这一点,就像扩展SP以返回更少但“更宽”的行和更多的列一样
另一个复杂问题是,一个检查可能有另一个检查缺少的行,在这种情况下,解决方案是添加空值或“-”
另外,这是在使用Sql Server 2012。您应该使用Sql Server
Pivot
。它将行转换为列。如果您使用的是mssql 2005+,那么您可以有一个最简单的开始。您可以使用如下轴:
测试数据
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
编辑
正如朱哈尔在评论中所说:
生成的列名(表中的值)是在生成查询时生成的。这可能需要另一个初始查询才能获取
编辑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
这不需要枢轴,可以在大多数RDM上使用如果您想动态地执行此操作,而不必知道所有的
Desc
值是什么,您可以构建枢轴查询并使用Exec()
或执行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)
如果希望-
为空值,则需要创建另一个变量来保存sql的选择部分的转换脚本
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)
使用pivot
,它将完成尽可能草率的工作。你应该提供一个完整的答案,而不仅仅是“删除”一个功能/关键字/机制并完成它。@Amit如果有任何代码或我可以解释的东西,我一定会这样做。这是我能回答的最好的“得到建议”类型的问题。我想你可以提供一个最小的例子来说明如果问题中有样本数据,这将如何工作,或者我会对问题本身进行评论,解释为什么这样的问题不适合这样做(因为它们会导致像你这样的答案),甚至可能投票给close。但这只是我的意见…:-)(另请看@Arion的答案)对我来说没关系,我很快会尝试一下,如果你的回答能解决我试图问的问题,我会接受你的回答:)如果不能,我就必须重新措辞这个问题。同意这个样本数据。将在将来完成:)应该注意,这要求OP在构建查询时知道结果列名(表中的值)是什么。这可能需要另一个初始查询才能获取。@juharr:更新了答案谢谢。这一条提供了解决我的问题的最多提示,将其标记为公认的答案。