/*需求: 合并列值.
无论是在sql 2000, 还是在 sql 2005 中,都没有提供字符串的聚合函数,
所以, 当我们在处理下列要求时,会比较麻烦:表数据:
id value
----- ------
1 aa
1 bb
2 aaa
2 bbb
2 ccc
需要得到结果:
id values
------ -----------
1 aa,bb
2 aaa,bbb,ccc
即, group by id, 求 value 的字符串相加的值*/
--示例演示: 首先创建临时表数据
CREATE TABLE #A(id INT ,value0 VARCHAR(50))
INSERT INTO #A
SELECT 1, 'aa'
UNION ALL
SELECT 1, 'bb'
UNION ALL
SELECT 2, 'aaa'
UNION ALL
SELECT 2, 'bbb'
UNION ALL
SELECT 2, 'ccc'
SELECT * FROM #A
-- 0、简义方式:动态赋值 合并某一个相同项的值
DECLARE @sql VARCHAR(1000)
SELECT @sql=COALESCE(@sql+',','')+ value0 FROM #A WHERE id = 2
SELECT @sql
-- ======================
--1. 使用用户标量函数, 合并相同项的值
--=======================
CREATE FUNCTION dbo.ufn_Append(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + ',' + value0
FROM #A
WHERE id=@id
RETURN STUFF(@r, 1, 1, '') --清除第一个;分隔符
END
GO
-- 调用函数
SELECt id, values=dbo.ufn_Append(id)
FROM #A
GROUP BY id
-- =========================
-- 使用CTE嵌套查询 for sqlserver 2005 特性
-- =========================
WITH tb1(id,totalCount,col_List,value0,curr_count)
AS (
SELECT id, -- 区别关键列
COUNT(*) OVER(PARTITION BY id), -- 作外表区分列时使用
CAST(value0 AS VARCHAR(2000)), --为确认值是字符串相加,转换,待合并的列值
value0, --区别副列
1 --计数列
FROM #A
UNION ALL
SELECT tb1.id,
tb1.totalCount,
CAST(tb1.col_List + ',' + e.value0 AS VARCHAR(2000)), --合并列值
e.value0,
tb1.curr_count + 1 --当前积累计数
FROM #A e,tb1 -- 循环,返回左右两表交叉的所有记录
WHERE e.id = tb1.id AND e.value0 > tb1.value0 -- 筛选有用数据,书名死循环
)
--SELECT * FROM tb1 ORDER BY 1 /*查询嵌套表数据*/
SELECT id,col_List FROM tb1
WHERE totalCount = curr_count
ORDER BY 1 /*列出合并列值后的值*/
--SELECT * FROM #A ORDER BY 1 /*查询源表数据*/
--================= =================
--OUTER APPLY返回左右两表的所有行 for sqlserver 2005
--==================================
SELECT *
FROM(
SELECT DISTINCT
id
FROM #A
)A
OUTER APPLY(
SELECT
[values]= STUFF(REPLACE(REPLACE(
(
SELECT value FROM #A N
WHERE id = A.id
FOR XML AUTO
), '<N value="', ','), '"/>', ''), 1, 1, '')
)N
部分资料参考:http://www.cnblogs.com/wintersun/archive/2008/11/30/1344347.html