需求:按照分組,將多條記錄內容合併成一條,效果如下: 資料庫示例: 根據不同的SQL版本,可以有以下方法: 一、SQL 2000 不支持FOR XML,不支持CONCAT。只能寫自定義函數。 二、SQL 2012 支持 concat,2000版本自定義函數的基礎上可少量優化 三、SQL2005支持f ...
需求:按照分組,將多條記錄內容合併成一條,效果如下:
資料庫示例:
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就可以了,見三。