sqlserver中 多條數據合併成一條數據 (stuff 與 for xml path 連用)

需求:按照分組,將多條記錄內容合併成一條,效果如下:

數據庫示例:

複製代碼

複製代碼

CREATE TABLE [t2]([NID] [bigint] NULL,[district] [nvarchar](255) NULL,[town] [nvarchar](255) NULL);
insert into t2 values(1,'淮上區','曹老集鎮');
insert into t2 values(2,'淮上區','淮濱街道');
insert into t2 values(3,'淮上區','梅橋鄉');
insert into t2 values(4,'淮上區','吳小街鎮');
insert into t2 values(5,'淮上區','小蚌埠鎮');
insert into t2 values(1,'光明新區','公明街道');
insert into t2 values(2,'光明新區','光明街道');
insert into t2 values(1,'吉利區','大慶路街道');
insert into t2 values(2,'吉利區','吉利鄉');

複製代碼

複製代碼

 

根據不同的SQL版本,可以有以下方法:

一、SQL 2000 不支持FOR XML,不支持CONCAT。只能寫自定義函數。

複製代碼

複製代碼

CREATE FUNCTION dbo.townconcat(@district nvarchar(255)) 
RETURNS varchar(8000) 
AS 
BEGIN 
    DECLARE @str varchar(8000) 
    SET @str = '' 
    SELECT @str = @str + ',' + town FROM t2 WHERE district=@district 
    RETURN STUFF(@str, 1, 1, '') 
END 
GO 
-- 調用函數 
SELECt district, town = dbo.townconcat(district) FROM t2 GROUP BY district 

drop function dbo.townconcat
go

複製代碼

複製代碼

二、SQL 2012 支持 concat,2000版本自定義函數的基礎上可少量優化

複製代碼

複製代碼

--將2000版中的
SELECT @str = @str + ',' + town FROM t2 WHERE district=@district
--變成
SELECT @str = concat(@str,',',town) FROM t2 WHERE district=@district 

其他代碼不變

複製代碼

複製代碼


三、SQL2005支持for xml,可以大量簡化

select distinct a.district,
(SELECT town+','FROM t2 where district=a.district FOR XML PATH(''))as towns 
from t2 a

 

以上三種方法都可以實現同樣的效果。效果第一段的需求中的效果。

 

四、分析:
以上3種方法各有優劣,個人喜歡for xml的方式,因爲夠簡單,一條select解決,可以直接適用於各視圖中。

核心的代碼是:

SELECT town+','FROM t2  FOR XML PATH('')

上面的代碼得到的結果爲:

注:
1、上圖中的列名是自動生成的,不可以通過as 來命名。
2、我們不可以select多列,比如SELECT district,town+',' as tt FROM t2  FOR XML PATH('')。

如果加上,並不會報錯,但效果可能不是我們想要的,如下圖:

 

那我們如何根據關鍵字段來分組呢,我們可以把(select ..FOR XML..)作爲子查詢生成字段,看下圖:

得到上圖就明白了吧,直接用distinct就可以了,見三。

 

---------------------------------------------

附錄

兩種sql 方式:

複製代碼

第一種:  select distinct a.type,
(SELECT title+','FROM wk_CarInfo where type=a.type FOR XML PATH(''))as towns 
from wk_CarInfo a

------------------
第二種,性能高:SELECT  type ,STUFF((SELECT title+',' FROM wk_CarInfo 
 WHERE t_u.type=type order by title
FOR XML PATH('')),1,0,'') AS title
FROM  wk_CarInfo as t_u
GROUP BY type

複製代碼

轉自:https://www.cnblogs.com/flysem/p/10282205.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章