是否可以在T-SQL中将行转换为可变数量的列?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在T-SQL中将行转换为可变数量的列?相关的知识,希望对你有一定的参考价值。
我有一个奇怪的要求,我需要将可变数量的行转换为列。我需要帮助确定是否可以在SQL中完成,或者我是否应该用不同的语言编写程序。
假设我有一个表客户端,它只保存最少的客户端数据。然后,一个名为Attributes的表,它命名不同的可能属性(例如,电话号码,地址等)。最后,我有第三个表ClientAttributes,它包含两个FK和值。
所以对于每个客户端,我有任意数量的属性。客户端可以包含零个,1个或无限的电话号码,零个,1个或无限地址,依此类推。
我需要的是所有数据的表格视图。客户名称,电话,电话2,电话3,...,地址,地址2,地址3 ....等等。如果客户端没有此值,则该值将为null。显然,这意味着每次执行查询时列数可能不同。
这需要与SQL Server 2008兼容。
这可以纯粹在T-SQL中完成,还是应该通过转储数据并让C#处理它来做客户端?我可以在C#中轻松完成,但我不确定这可以在SQL中完成。 SQL将是首选,因为数据集可能太大而无法容纳在RAM中。
如果需要,可以通过动态sql在SQL中完成。为一个项目(我将使用手机)执行此操作的基本理论如下,您将为所需的其他列分组重复此操作。请注意,没有人会说它很漂亮。
- 创建一个基本查询(CTE,TEMP表,无论如何),获取每个有效电话号码的客户ID,电话。添加一个rownumber“ROW_NUMBER()OVER(PartID by ClientID ORDER BY(what))” - 我将它称为basedata
- 从basedata获取max row_number - 这是您需要的电话列数
通过从i = 1循环到MaxRowNo来创建动态SQL查询字符串的一部分。在每个循环中,您将构建一个选择字符串和一个连接字符串。选择字符串应在每个循环中添加如下内容
Set @SelectStr = @SelectStr + 'P' + cast(i as varchar(10)) + '.Phone,';
连接字符串应该在每个循环中添加这样的东西
Set @JoinStr = @JoinStr + ' left outer join baseData P' + cast(i as varchar(10)) + ' on P' + cast(i as varchar(10)) + '.ClientID = C.ClientID and P' + cast(i as varchar(10)) + '.RowNo = ' + cast(i as varchar(10));
您将对地址和任何其他重复的列组重复上述整个过程 - 确保不要将别名加倍。然后你可以通过添加查询的任何固定的,不变的部分(客户端数据)来组成你的最终动态sql查询,就像这样
Set @FinalQuery = 'SELECT C.ClientID, C.ClientName, ' + @SelectStr + ' From Client C ' + @JoinStr
你最后建立的查询(假设有最多三个电话和两个地址作为例子)看起来像这样 - 然后EXEC这个字符串
SELECT C.ClientID, C.ClientName, --any other client stuff you need here
P1.Phone, P2.Phone, P3.Phone, A1.Address, A2.Address
From Client C
left outer join baseData P1 on P1.ClientID = C.ClientID and P1.RowNo = 1
left outer join baseData P2 on P2.ClientID = C.ClientID and P2.RowNo = 2
left outer join baseData P3 on P3.ClientID = C.ClientID and P3.RowNo = 3
left outer join baseAddr A1 on A1.ClientID = C.ClientID and A1.RowNo = 1
left outer join baseAddr A2 on A2.ClientID = C.ClientID and A2.RowNo = 2
以上是关于是否可以在T-SQL中将行转换为可变数量的列?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Oracle sql中将行转换为按多列分组的列[关闭]
在 Seaborn 中将相关矩阵绘制为热图时,是不是可以删除重复的列/行?