MSSQL中几种字符串聚合方式

USE TEMPDB

GO

IF OBJECT_ID('TB') IS NOT NULL DROP TABLE TB

GO

CREATE TABLE TB(

ID INT

,VAL VARCHAR(50)

)

GO

INSERT INTO TB

SELECT 1,'A2' UNION ALL

SELECT 1,'A1' UNION ALL

SELECT 2,'B1' UNION ALL

SELECT 2,'B2' UNION ALL

SELECT 3,'C1'

GO

IF OBJECT_ID('FUN_MU') IS NOT NULL DROP FUNCTION FUN_MU

GO

--自定义函数方式

CREATE FUNCTION FUN_MU(@ID INT)

RETURNS VARCHAR(MAX)

AS

BEGIN

DECLARE @STR VARCHAR(MAX)

SELECT @STR=ISNULL(@STR+',','')+VAL

FROM TB

WHERE ID=@ID

ORDER BY VAL 

RETURN @STR

END

GO

SELECT ID,DBO.FUN_MU(ID)

FROM TB

GROUP BY ID

/*

1 A1,A2

2 B1,B2

3 C1

*/

/*

这个方法我比较常用,效率不错,兼容2K,配置比较灵活,不过缺点就是每次都要新建一个函数 -_-||

拼接时的方式比较灵活,这里用ISNULL只是为了去掉第一个逗号,还有一些其它的写法不一一列出了。

*/

--XML方式

SELECT ID

,STUFF(

(SELECT ','+VAL FROM TB T2 WHERE T2.ID=T1.ID ORDER BY VAL FOR XML PATH(''))

,1,1,'')

FROM TB T1

GROUP BY ID

/*

1 A1,A2

2 B1,B2

3 C1

*/

/*

2005以后的版本才能用,这是最精简的版本。这个写法的优点是可以直接用查询完成拼接,缺点就是大数据量时非常非常非常慢。

我在小数据量做聚合时常用。

*/

--CTE方式

;WITH MU AS (

SELECT *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY VAL) AS NID FROM TB

),MU2 AS (

SELECT ID,NID,CONVERT(VARCHAR(MAX),VAL) AS NVAL

FROM MU

WHERE NID=1

UNION ALL

SELECT 

MU.ID,MU.NID,MU2.NVAL+','+MU.VAL

FROM MU

INNER JOIN MU2 ON MU.ID=MU2.ID AND MU.NID=MU2.NID+1

)

SELECT ID,NVAL

FROM MU2 T1

WHERE NOT EXISTS(

SELECT 1 FROM MU2 T2 WHERE T2.ID=T1.ID AND T2.NID>T1.NID

)

ORDER BY ID

/*

1 A1,A2

2 B1,B2

3 C1

*/

/*

CTE也是2005以后才有的功能,拼接字符串只是一个功能,它的递归运算才是最好用的功能。

这种写法其实不太常用,因为它无法写到一个复杂查询中,只是经常作为一个CTE功能展示的例子

*/

原文地址:https://www.cnblogs.com/guguda/p/2130026.html