数据库管理与开发 阶梯

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

/*需求: 合并列值.
无论是在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

posted on 2012-05-30 10:39  zhou__zhou  阅读(555)  评论(0编辑  收藏  举报