帮大哥们写好了创建表的代码create table #tableTest 
(ID int identity,姓名 varchar(20),报读科目 varchar(20),费用 money)
go
insert into #tableTest
select '小明','语文',300 union all
select '小明','数学',500 union all
select '小明','英语',500 union all
select '小红','语文',300 union all
select '小红','数学',500
go
select *from #tableTest
现在的表的结果是这样的我要的结果是如下图的

解决方案 »

  1.   

    不不起各位大哥,我补充一下!
    请各位大哥不要用 stuff,,,,,for xml path('')的方法,这个方法如果是数据量太大的话,效率非常低
      

  2.   

    select [姓名],SUM([费用]),(select [报读科目]+'|' from #tableTest as a where a.姓名=b.姓名 for xml path('')) from #tableTest as b 
    group by [姓名]
      

  3.   

    我觉得你这种拼接本身就没有什么效率可言,不用stuff,,,,,for xml path('')的话就用函数循环,效率估计更低
      

  4.   


    xml处理   数据量大慢了也没办法
      

  5.   


    create table tableTest 
    (ID int identity,姓名 varchar(20),报读科目 varchar(20),费用 money)
    goinsert into tableTest
    select '小明','语文',300 union all
    select '小明','数学',500 union all
    select '小明','英语',500 union all
    select '小红','语文',300 union all
    select '小红','数学',500
    go
    select *from tableTestcreate function dbo.fn_mergeSTR(@name varchar(20),@split varchar(10))  
    returns varchar(300)  
    as  
    begin  
        declare @str varchar(300);  
          
        set @str = '';  
          
        select @str = @str + 报读科目 + @split  
        from tableTest  
        where 姓名 = @name  
          
        set @str = left(@str , len(@str) - LEN(@split) )  
          
        return @str   --返回值   
    end  
    go  
    select 姓名,
           报读科目,
           SUM(费用) as 费用
    from
    (
    select 姓名,
           dbo.fn_mergeSTR(姓名,'|') as 报读科目,
           费用
    from tableTest
    ) t
    group by 姓名,
             报读科目
    order by 3 desc/*
    姓名 报读科目 费用
    小明 语文|数学|英语 1300.00
    小红 语文|数学 800.00
    */
      

  6.   

    CLR没用过,函数要看怎么写,有对比案例不?
      

  7.   

    USE TEMPDB
    GO
    IF OBJECT_ID('TEST') IS NOT NULL DROP TABLE TEST
    IF OBJECT_ID('FUN_MU') IS NOT NULL DROP FUNCTION FUN_MU
    GO
    create table TEST 
    (ID int identity,NAME varchar(20),KEMU varchar(20),FEI money)
    go
    insert into TEST
    select '小明','语文',300 union all
    select '小明','数学',500 union all
    select '小明','英语',500 union all
    select '小红','语文',300 union all
    select '小红','数学',500
    go
    CREATE INDEX INX_TABLETEST_NAME ON TEST(NAME)
    GO
    CREATE FUNCTION FUN_MU(@NAME VARCHAR(20))
    RETURNS VARCHAR(MAX)
    AS
    BEGIN
    DECLARE @STR VARCHAR(MAX)
    SELECT @STR=ISNULL(@STR+'|','')+KEMU
    FROM TEST
    WHERE NAME=@NAME
    RETURN @STR
    END
    GO
    select NAME AS [姓名],DBO.FUN_MU(NAME) AS [报读科目],SUM(FEI) AS [费用]
    from TEST
    GROUP BY NAME
    /*
    姓名 报读科目 费用
    小红 语文|数学 800.00
    小明 语文|数学|英语 1300.00
    */
      

  8.   

    我们之前做字符串聚合,大概1000W还是2000W的样子,XML一晚上没跑完,函数几十分钟跑出来了
      

  9.   

    CLR更快,不过也要看数据量,太大也还是出不来,有一次做两个千万级表JOIN后聚合也出不来了,最后是分批聚合出来的
      

  10.   

    这种是递归实现方式,不过有点中看不中用,呵呵:
    create table tableTest 
    (ID int identity,姓名 varchar(20),报读科目 varchar(20),费用 money)
    goinsert into tableTest
    select '小明','语文',300 union all
    select '小明','数学',500 union all
    select '小明','英语',500 union all
    select '小红','语文',300 union all
    select '小红','数学',500
    go
    select *from tableTest;WITH c
    AS
    (
    SELECT id,
           姓名, 
           报读科目,
           费用,
           row_number() OVER(PARTITION BY 姓名   --通过分组再排序,把需要连接的字符串排在一起
                                 ORDER BY id) AS rownum
    FROM tableTest
    ),cc
    as
    (
    SELECT 姓名,
           CAST(报读科目 AS varchar(1000)) AS 报读科目,
           费用,
           rownum,
           1 AS level
    FROM cUNION ALLSELECT cc.姓名,
           CAST(cc.报读科目 +'|'+ c.报读科目 AS VARCHAR(1000)),  --保存连接的字符串
           cc.费用 + c.费用,
           cc.rownum+1,
           LEVEL + 1
    FROM cc,c
    WHERE cc.姓名 = c.姓名 AND
          cc.rownum + 1 = c.rownum   --通过rownum加1,和下一个字符串连接
    )SELECT 姓名,报读科目,费用 FROM cc
    WHERE level = (SELECT max(level) FROM cc c2 WHERE c2.姓名 = cc.姓名 )
      

  11.   

    不过CLR容易造成外部资源等待,sqlserver对外部资源控制鞭长莫及