本文轉載於T-Sql:字串分組彙總,也許你還有更簡單的辦法?
今天在看訂閱的RSS的時候,看到這麼一個問題:T-Sql中如何對分組的資訊進行彙總,並以逗號串連字元;也就是對一個表中的某個欄位進行分組,然後對另一個欄位彙總,如果表達得不太清楚,請看下面的表。
原表:
| Parent |
Child |
| Charles |
William |
| Charles |
Harry |
| Anne |
Peter |
| Anne |
Zara |
| Andrew |
Beatrice |
| Andrew |
Eugenie |
處理後的結果:
| Parent |
Children |
| Charles |
William,Harry |
| Anne |
Peter,Zara |
| Andrew |
Eugenie,Beatrice |
貌似很簡單,以我的思考,先寫一個彙總函式,然後再查詢語句裡面調用這個彙總函式;實際上還有更簡單的辦法,這是作者給出的解決辦法,沒有用到自訂彙總函式,他用的是FOR XML PATH(‘’)這樣的處理方式,感覺真是爽
with t as(
select 'Charles' parent, 'William' child union
select 'Charles', 'Harry' union
select 'Anne', 'Peter' union
select 'Anne', 'Zara' union
select 'Andrew', 'Beatrice' union
select 'Andrew', 'Eugenie'
)
SELECT parent, STUFF( ( SELECT ','+ child
FROM t a
WHERE b.parent = a.parent
FOR XML PATH('')),1 ,1, '') children
FROM t b
GROUP BY parent
複製代碼
如果你還有其他的解決辦法,希望你也能給出你的答案, 多多益善
考慮到不熟悉STUFF()這個函數,故根據這個思路自己寫了另外的方法:
select parent,right(list,len(list)-1) from
(
select parent,
(SELECT ','+ children
FROM t a
where a.parent=b.parent
FOR XML PATH('')) as list
from t b
group by parent
) x
最終查詢出來的結果集和使用上面的Stuff函數是一樣的.
另外補充一下關於Stuff函數的用法:
/* 用法描述: Stuff(expression1_Str,startIndex,lengthInt,expression2_Str)函數共有四個參數,其功能是將expression1_Str中自startIndex位置起刪除lengthInt個字元,然後將expression2插入到expression1_Str中的startIndex位置。 */ select 'abcdefg' select STUFF('abcdefg',1,0,'1234') --結果為'1234abcdefg' select STUFF('abcdefg',1,1,'1234') --結果為'1234bcdefg' select STUFF('abcdefg',2,1,'1234') --結果為'a1234cdefg' select STUFF('abcdefg',2,2,'1234') --結果為'a1234defg' --一般的程式設計語言和Sql語言一樣,都把字串當作字元數組處理,但一個差別在於,大多數程式設計語言的數組下標起始位為0,而Sql Server中為1,由於慣性思維,常常把一般程式設計語言中的0起始位帶至SQL編程中。 |
原表:
| Parent |
Child |
| Charles |
William |
| Charles |
Harry |
| Anne |
Peter |
| Anne |
Zara |
| Andrew |
Beatrice |
| Andrew |
Eugenie |
處理後的結果:
| Parent |
Children |
| Charles |
William,Harry |
| Anne |
Peter,Zara |
| Andrew |
Eugenie,Beatrice |
貌似很簡單,以我的思考,先寫一個彙總函式,然後再查詢語句裡面調用這個彙總函式;實際上還有更簡單的辦法,這是作者給出的解決辦法,沒有用到自訂彙總函式,他用的是FOR XML PATH(‘’)這樣的處理方式,感覺真是爽
with t as(
select 'Charles' parent, 'William' child union
select 'Charles', 'Harry' union
select 'Anne', 'Peter' union
select 'Anne', 'Zara' union
select 'Andrew', 'Beatrice' union
select 'Andrew', 'Eugenie'
)
SELECT parent, STUFF( ( SELECT ','+ child
FROM t a
WHERE b.parent = a.parent
FOR XML PATH('')),1 ,1, '') children
FROM t b
GROUP BY parent
複製代碼
如果你還有其他的解決辦法,希望你也能給出你的答案, 多多益善