[英]Is it possible to convert rows to a variable number of columns in T-SQL?
我有一個奇怪的要求,我需要將數量可變的行轉換為列。 我需要幫助弄清楚這是否可以用SQL來完成,或者我是否應該只使用其他語言編寫程序。
假設我有一個表Clients,該表僅包含最少的客戶端數據。 然后,有一個稱為屬性的表,該表命名了不同的可能屬性(例如,電話號碼,地址等)。 最后,我有第三個表ClientAttributes,其中包含兩個FK和值。
因此,對於每個客戶端,我都有許多屬性。 客戶端可以有零個,1個或無限的電話號碼,零個,1個或無限的地址,依此類推。
我需要的是所有這些數據的表格視圖。 客戶端名稱,電話,電話2,電話3,...,地址,地址2,地址3 ....等。 如果客戶端沒有這樣的值,則該值為null。 顯然,這意味着每次執行查詢時,列數可能會有所不同。
這需要與SQL Server 2008兼容。
可以僅在T-SQL中完成此操作,還是應該僅通過轉儲數據並讓C#處理它來在客戶端進行此操作? 我可以輕松地在C#中做到這一點,但是我不確定這可以在SQL中完成。 首選SQL,因為數據集可能太大而無法放入RAM。
如果需要,可以通過動態sql在SQL中完成。 對一項(我將使用電話)執行此操作的基本理論如下,您將針對所需的其他列分組重復此操作。 請注意,沒有人會說它很漂亮。
通過從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
您最終建立的查詢(假設最多三個電話和兩個地址為例)看起來像這樣-然后執行此字符串
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.