网络游戏 2017-05-26
本文出处:http://www.cnblogs.com/wy123/p/6910468.html
感觉最近sql也没少写,突然有一点生疏了,对于用的不是太频繁的一些操作,时间一久就容易生。
多行的某一个列合并成一个列
CREATE TABLE TestColumnMergeAndSplit
(
Id int Identity(1,1),
BusinessId int,
BusinessValue varchar(20)
)
GO
INSERT INTO TestColumnMergeAndSplit
SELECT 1,'AAA'
UNION ALL
SELECT 1,'BBB'
UNION ALL
SELECT 1,'CCC'
UNION ALL
SELECT 2,'XXX'
UNION ALL
SELECT 2,'YYY'
UNION ALL
SELECT 2,'ZZZ'
GO
SELECT * FROM TestColumnMergeAndSplit
GO
SELECT t1.BusinessId,
STUFF
(
( SELECT ','+t2.BusinessValue
FROM TestColumnMergeAndSplit t2
WHERE t2.BusinessId = t1.BusinessId
FOR
XML PATH('')
),
1,1,''
)
AS ColNames
FROM TestColumnMergeAndSplit t1
GROUP BY t1.BusinessId
GO 
另外是一个相反的操作,借助上面合并之后的结果,将一个多个值的字符串列拆分开来,转换为多行,

用到的字符串拆分函数,比较常见
CREATE FUNCTION [dbo].[fn_SplitStringToTable]
(
@s VARCHAR(max),
@split VARCHAR(10)
)
RETURNS @re TABLE
(
Id INT IDENTITY(1,1),
Value VARCHAR(100)
)
AS
BEGIN
IF @s IS NULL
RETURN
IF @split IS NULL
RETURN
IF(LEN(@split)<=0)
BEGIN
INSERT INTO @re VALUES (@s)
RETURN
END
DECLARE @splitlen INT
SET @splitlen=LEN(@split ) - 1
WHILE CHARINDEX(@split, @s) > 0
BEGIN
INSERT @re VALUES(LEFT(@s, CHARINDEX(@split, @s) - 1))
SET @s=STUFF(@s, 1, CHARINDEX(@split, @s) + @splitlen, '')
END
INSERT @re VALUES(@s)
RETURN
END 测试脚本,没啥技术含量
CREATE TABLE TestColumnMergeAndSplit
(
Id int Identity(1,1),
BusinessId int,
BusinessValue varchar(20)
)
GO
INSERT INTO TestColumnMergeAndSplit
SELECT 1,'AAA'
UNION ALL
SELECT 1,'BBB'
UNION ALL
SELECT 1,'CCC'
UNION ALL
SELECT 2,'XXX'
UNION ALL
SELECT 2,'YYY'
UNION ALL
SELECT 2,'ZZZ'
GO
SELECT * FROM TestColumnMergeAndSplit
GO
--合并多列为一列
SELECT t1.BusinessId,
STUFF
(
( SELECT ','+t2.BusinessValue
FROM TestColumnMergeAndSplit t2
WHERE t2.BusinessId = t1.BusinessId
FOR XML PATH('')
),
1,1,''
)
AS ColString
FROM TestColumnMergeAndSplit t1
GROUP BY t1.BusinessId
GO
SELECT * FROM TestColumnMergeAndSplit_BAK
GO
SELECT t1.BusinessId,t1.ColString,t2.Id,t2.Value
FROM TestColumnMergeAndSplit_BAK t1
CROSS APPLY dbo.fn_SplitStringToTable(ColString,',')t2
GO