利用 T-sql 的從句 for xml path('') 實現多行合併到一行, 並帶有分隔符
阿新 • • 發佈:2019-02-09
T-sql 有一個for xml path('')的從句能把多行結果合併到一行,併成為xml 格式
比如有一張表tb有兩列,其格式和資料為:
id value
—————
1 aa
1 bb
2 aaa
2 bbb
2 ccc
如果對其執行sql:
select id, value from tb for xml path('tbnode')
則返回的結果集僅為一行一列:
<tbnode><id>1</id><value>aa</value><id>1</id><value>bb</value>........<id>2</id><value>ccc</value></tbnode>
現在我們取巧一點, 省略path括號裡的內容, 同時把這兩列想辦法變成匿名列,sql如下:
select id+'',value+'' from tb for xml path('')
那麼返回結果如下(也是一個一行一列):1aa1bb2aaa2bbb2ccc
基於這樣的思路, 現在要對所有不同的ID的value進行合併,希望得到如下的結果集:
id value
—————
1 aa,bb
2 aaa,bbb,ccc
首先我們來構造右邊一列:
sql如下:
select value+',' from tb where ID=1 for xml path('')
這樣就可以得到 "aa,bb," 。但是最後面會多一個逗號,可以在外面再套一層select,並利用SUBSTRING()函式來去掉它。 在網上的其他方法中也有把逗號加在value前,然後用stuff函式來去掉最前面多餘的逗號的,詳見參考連結。substring的缺點是用len函式的時候還要再填一遍“select value+',' from tb where ID=1 for xml path('')“,會顯得冗長。
最後完整的sql如下:
select id,
valuelist=substring((select value+',' from tb where tb.id=a.id for xml path('')),
1,
len((select value+',' from tb as b where b.id=a.id for xml path('')))-1)
from tb as a
group by id
或者用stuff:
select id,valuelist=stuff((select ','+value from tb as b where b.ID=a.ID for xml path('')),1,1,'') from tb as a group by id
參考連結: http://www.cnblogs.com/WindBlog/archive/2011/07/06/2099219.html
轉者注:
for xml path('') 返回型別為nvarchar(max)