meteo***ll 關注
寫個綜合檢視,遇到個情況,需要對字串進行聚合統計,簡化如下:
任務號提交人
完工數周轉車號
x01張三
300v001
x01李四
200v002
x02王五
600v003
x02馬六
400v004
x02趙七
100v005
目的是:需要列出統計任務的完成資訊如下:
任務號提交人
完工數周轉車號
x01張三,李四
500v001,v002
x02王五,馬六,趙七
1100
v003,v004,v005
完工數量可以直接sum 後 group by,但是提交人 和 周轉車 字串欄位就很麻煩了。google了下,有以下三種辦法:
select taskid,sum(qty),
dbo.strjoin(workername,',') as workers, dbo.strjoin(cartno,',') as carts
from taskexecs group by taskid
是不是很簡單?而且以後出現類似的拼接字串聚合就都直接呼叫就好了,一副一勞永逸的姿態。
我對原文的方法做了一些小調整和改變,具體實現如下:
visual studio 2015,新建個專案--》模板選sql server 資料庫專案,命名專案sqlutil
新建項--》 sql clr c# ==>sql clr c# 聚合 ,是個類,命名strjoin.cs
using system;
using system.data;
using system.data.sqlclient;
using system.data.sqltypes;
using microsoft.sqlserver.server;
using system.text;、
[serializable]
[sqluserdefinedaggregate(
format.userdefined, //use custom serialization to serialize the intermediate result
isinvarianttonulls = true, //optimizer property
isinvarianttoduplicates = false, //optimizer property
isinvarianttoorder = false, //optimizer property
maxbytesize = 8000), //maximum size in bytes of persisted value
]public struct strjoin : ibinaryserialize
public void accumulate(sqlstring value,sqlstring contchar)
else
} public void merge(strjoin group)
public sqlstring terminate()
return new sqlstring(output);
} // this is a place-holder member field
#region ibinaryserialize members
public void read(system.io.binaryreader r)
public void write(system.io.binarywriter w)
#endregion
}
說明:看上去一臉矇逼很複雜的樣子,其實以上函式有效的部分很簡單,重點部分就是
在accumulate函式中:傳入引數,把字串拼起來。
在terminate函式中: 去掉最後乙個連線符並輸出。
主要看這兩個動作,就知道了。
在sqlserver中執行如下:
--開啟sqlserver的clr功能
exec sp_configure 'clr enabled', 1
reconfigure with override
go--註冊dll
create assembly sqlutil from 'c:\sqlutil.dll' --生成的dll路徑
go--註冊函式
create aggregate [dbo].[strjoin] (@value [nvarchar](max),
@contchar [nvarchar](2))
returns [nvarchar](max)
external name [sqlutil].[strjoin]
這樣後,就可以愉快的使用了。
如果要更新dll,需要先drop,在create
順序是 刪除引用的函式-->刪除dll
drop aggregate strjoin
drop assembly sqlutil
ps:在這個過程遇到個糾結的問題,就是虛擬機器和遠端機之間複製檔案的時候,居然會有問題,導致乙個更新的dll一直是舊版本,而我卻以為**有錯。。。。最後用.net refector去看dll的函式,才驚覺這個問題,**中.... 最後還是用共享傳的檔案。*** ps2:據說mysql和oracle其實都有現成的group_contact 和 wm_concat,所以到了sqlserver2012,據說也支援了字串聚合的函式。但是在使用2012之前,等於是用第三種方法提前體驗了而已。 SQL Server字串聚合拼接辦法
網上搜了一圈還是有不錯的方法的,比如stuff函式,我們可以這麼寫得到上面的結果 select type stuff select name fromtest b where b.type a.type for xml path 1 1,names fromtest a group by type ...
SQL Server字串聚合拼接辦法
資料範例如下 要得到的結果目標,獲取type相同的所有names拼接在一起的字串 sqlserver並沒有乙個直接拼接字串的函式,下面所提到的方法,只是日常的開發中自己個人用到的一些思路,僅供參考!declare temptable table type int,name nvarchar 100 ...
HANA Oracle字串聚合函式
應用場景 在資料進行分組時,需要將字串型別的字段進行聚合。如需將資料更改為 company dept pcode 公司1部門1 100254 公司1部門2 100245 company dept 公司1部門1,部門2 1 oracle中使用wm concat 或listagg 函式,注意最好要加上t...