数据资料:tb:
id      iQuantity
----------------
1        100
2        130   tbs:
id      Cname     iQuantity 
---------------------------
1        A          10
2        B          8 
1        C          10
1        F          10
2        F          15注:两表以ID字段作关连要求结果是:
id      iQuantity   CNAME    Already   remaining
------------------------------------------------
1        100       A,C,F      30         70
2        130       B,F        23         107 id    

解决方案 »

  1.   

    SET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GO
    --得到字符串学生ID
    ALTER  FUNCTION [GetStrID]
    (
    --班级号
    @ID int
    )
    RETURNS nvarchar(100)
    AS
    BEGIN
    DECLARE @Name nvarchar(100)
            SELECT @Name = ''
    SELECT @Name = @Name+ID FROM 班级表 WHERE ID=-@ID
    RETURN @NameEND
    GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO 要写一个得到字符串
      

  2.   

    /****************************************************************************************************************************************************** 
    合并分拆表数据 整理人:中国风(Roy) 日期:2008.06.06 
    ******************************************************************************************************************************************************/ --> --> (Roy)生成測試數據 if not object_id('Tab') is null 
        drop table Tab 
    Go 
    Create table Tab([Col1] int,[Col2] nvarchar(1)) 
    Insert Tab 
    select 1,N'a' union all 
    select 1,N'b' union all 
    select 1,N'c' union all 
    select 2,N'd' union all 
    select 2,N'e' union all 
    select 3,N'f' 
    Go 合并表: SQL2000用函数: go 
    if object_id('F_Str') is not null 
        drop function F_Str 
    go 
    create function F_Str(@Col1 int) 
    returns nvarchar(100) 
    as 
    begin 
        declare @S nvarchar(100) 
        select @S=isnull(@S+',','')+Col2 from Tab where Col1=@Col1 
        return @S 
    end 
    go 
    Select distinct Col1,Col2=dbo.F_Str(Col1) from Tab go SQL2005用XML: 方法1: select 
        a.Col1,Col2=stuff(b.Col2.value('/R[1]','nvarchar(max)'),1,1,'') 
    from 
        (select distinct COl1 from Tab) a 
    Cross apply 
        (select COl2=(select N','+Col2 from Tab where Col1=a.COl1 For XML PATH(''), ROOT('R'), TYPE))b 方法2: select 
        a.Col1,COl2=replace(b.Col2.value('/Tab[1]','nvarchar(max)'),char(44)+char(32),char(44)) 
    from 
        (select distinct COl1 from Tab) a 
    cross apply 
        (select Col2=(select COl2 from Tab  where COl1=a.COl1 FOR XML AUTO, TYPE) 
                    .query(' <Tab> 
                    {for $i in /Tab[position() <last()]/@COl2 return concat(string($i),",")} 
                    {concat("",string(/Tab[last()]/@COl2))} 
                    </Tab>') 
                    )b SQL05用CTE: ;with roy as(select Col1,Col2,row=row_number()over(partition by COl1 order by COl1) from Tab) 
    ,Roy2 as 
    (select COl1,cast(COl2 as nvarchar(100))COl2,row from Roy where row=1 
    union all 
    select a.Col1,cast(b.COl2+','+a.COl2 as nvarchar(100)),a.row from Roy a join Roy2 b on a.COl1=b.COl1 and a.row=b.row+1) 
    select Col1,Col2 from Roy2 a where row=(select max(row) from roy where Col1=a.COl1) order by Col1 option (MAXRECURSION 0) 
    生成结果: 
    /* 
    Col1        COl2 
    ----------- ------------ 
    1          a,b,c 
    2          d,e 
    3          f (3 行受影响) 
    */ 
    --参考
    拆分表:--> --> (Roy)生成測試數據
     
    if not object_id('Tab') is null
        drop table Tab
    Go
    Create table Tab([Col1] int,[COl2] nvarchar(5))
    Insert Tab
    select 1,N'a,b,c' union all
    select 2,N'd,e' union all
    select 3,N'f'
    Go--SQL2000用辅助表:
    if object_id('Tempdb..#Num') is not null
        drop table #Num
    go
    select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b
    Select 
        a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) 
    from 
        Tab a,#Num b
    where
        charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
    --2000不使用辅助表
    Select
        a.Col1,COl2=substring(a.Col2,b.number,charindex(',',a.Col2+',',b.number)-b.number) 
    from 
        Tab a join master..spt_values  b 
        ON B.type='p' AND B.number BETWEEN 1 AND LEN(A.col2)
    where
         substring(','+a.COl2,b.number,1)=','
    SQL2005用Xml:select 
        a.COl1,b.Col2
    from 
        (select Col1,COl2=convert(xml,'<root><v>'+replace(COl2,',','</v><v>')+'</v></root>') from Tab)a
    outer apply
        (select Col2=C.v.value('.','nvarchar(100)') from a.COl2.nodes('/root/v')C(v))b
    SQL05用CTE:;with roy as 
    (select Col1,COl2=cast(left(Col2,charindex(',',Col2+',')-1) as nvarchar(100)),Split=cast(stuff(COl2+',',1,charindex(',',Col2+','),'') as nvarchar(100)) from Tab
    union all
    select Col1,COl2=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from Roy where split>''
    )
    select COl1,COl2 from roy order by COl1 option (MAXRECURSION 0)生成结果:
    /*
    Col1        COl2
    ----------- -----
    1           a
    1           b
    1           c
    2           d
    2           e
    3           f
    */
      

  3.   

    --> 测试数据:[tb]
    if object_id('[tb]') is not null drop table [tb]
    go
    create table [tb]([id] int,[iQuantity] int)
    insert [tb]
    select 1,100 union all
    select 2,130--> 测试数据:[tbs]
    if object_id('[tbs]') is not null drop table [tbs]
    go
    create table [tbs]([id] int,[Cname] varchar(1),[iQuantity] int)
    insert [tbs]
    select 1,'A',10 union all
    select 2,'B',8 union all
    select 1,'C',10 union all
    select 1,'F',10 union all
    select 2,'F',15--------------------------------查询开始------------------------------
    select * from [tb] a,
    (
    select[id], [Cname]=stuff((select ','+[Cname] from [tbs] t where id=[tbs].id for xml path('')), 1, 1, ''),sum([iQuantity]) as [iQuantity]
    from [tbs]
    group by [id]
    ) b
    where a.id=b.id
    /*
    id          iQuantity   id          Cname             iQuantity
    ----------- ----------- ----------- --------------------------------
    1           100         1           A,C,F                30
    2           130         2           B,F                  23(2 行受影响)
    */
      

  4.   


    CREATE TABLE #tb
    (
    id int,
    iQuantity int
    )CREATE TABLE #tbs
    (
    id int,
    cname varchar,
    iQuantity int
    )INSERT INTO #tb
    SELECT 1,100 UNION ALL
    SELECT 2,130INSERT INTO #tbs
    SELECT 1,'A',10 UNION ALL 
    SELECT 2,'B',8  UNION ALL 
    SELECT 1,'C',10 UNION ALL 
    SELECT 1,'F',10 UNION ALL 
    SELECT 2,'F',15
    SELECT
    a.id,
    a.iQuantity,
    stuff((select ',' + cname from #tbs where id = a.id for xml path('')),1,1,''),
    sum(b.iQuantity),
    a.iQuantity-sum(b.iQuantity)
    FROM 
    #tb a join
    #tbs b ON a.ID = b.ID
    GROUP BY
    a.id,
    a.iQuantity
    1 100 A,C,F 30 70
    2 130 B,F 23 107
      

  5.   

    --建立测试环境
    IF OBJECT_ID('tb') IS NOT NULL  DROP TABLE tb
    GO
    CREATE TABLE tb
    (
    id int identity, 
    iQuantity int,
        CONSTRAINT PK_TB PRIMARY KEY (id)
    )
    GO
    INSERT TB
    SELECT 100 union
    select 130
    go
    IF OBJECT_ID('tbs') IS NOT NULL  DROP TABLE tbs
    GO
    CREATE TABLE tbs
    (
    id int , 
    Cname varchar(10),
    iQuantity int
    )
    GO
    INSERT tbs
    SELECT 1,'A',10 union all
    SELECT 2,'B',8 union all
    SELECT 1,'C',10 union all
    SELECT 1,'F',10 union all
    SELECT 2,'F',15 
    go
    create function dbo.f_str(@id int) returns varchar(100)
    as
    begin
        declare @str varchar(1000)
        set @str = ''
        select @str = @str + ',' + Cname from tbs where id = @id
        set @str = right(@str , len(@str) - 1)
        return @str
    end
    go--查询
    select a.id,a.iQuantity,dbo.f_str(a.id) CNAME,
    sum(b.iQuantity) Already,a.iQuantity-sum(b.iQuantity) remaining
    from tb a  join tbs b on a.id=b.id
    group by a.id,a.iQuantity
    --结果
    /*(2 行受影响)(5 行受影响)
    id          iQuantity   CNAME                                                                                                Already     remaining
    ----------- ----------- ---------------------------------------------------------------------------------------------------- ----------- -----------
    1           100         A,C,F                                                                                                30          70
    2           130         B,F                                                                                                  23          107(2 行受影响)
    */
      

  6.   


    其实不光是今天,呆久了就发现,大部分都是问 行转列、字符连接/拆分、解BOM、分类汇总 这样的问题,应该对这几个问题搞个置顶贴,大家看过后,再问。
      

  7.   

    --> 测试数据:[tb]
    if object_id('[tb]') is not null drop table [tb]
    go
    create table [tb]([id] int,[iQuantity] int)
    insert [tb]
    select 1,100 union all
    select 2,130--> 测试数据:[tbs]
    if object_id('[tbs]') is not null drop table [tbs]
    go
    create table [tbs]([id] int,[Cname] varchar(1),[iQuantity] int)
    insert [tbs]
    select 1,'A',10 union all
    select 2,'B',8 union all
    select 1,'C',10 union all
    select 1,'F',10 union all
    select 2,'F',15--------------------------------查询开始------------------------------
    select *,remaining=iQuantity - Already from [tb] a,
    (
    select[id], [Cname]=stuff((select ','+[Cname] from [tbs] t where id=[tbs].id for xml path('')), 1, 1, ''),sum([iQuantity]) as Already 
    from [tbs]
    group by [id]
    ) b
    where a.id=b.id
    /*
    id          iQuantity   id          Cname      Already     remaining
    ----------- ----------- ----------- -------- ----------- ----------
    1       100        1          A,C,F    30            70
    2       130        2          B,F    23            107
     
    (2 行受影响)
    */
      

  8.   

    --> 测试数据: [ta]
    if object_id('[ta]') is not null drop table [ta]
    go
    create table [ta] (id int,iQuantity int)
    insert into [ta]
    select 1,100 union all
    select 2,130
    --> 测试数据: [tbs:]
    if object_id('[tbs]') is not null drop table [tbs]
    go
    create table [tbs] (id int,Cname varchar(1),iQuantity int)
    insert into [tbs]
    select 1,'A',10 union all
    select 2,'B',8 union all
    select 1,'C',10 union all
    select 1,'F',10 union all
    select 2,'F',15if object_id('f_str') is not null drop function f_str
    go
    create function f_str(@i int)
    returns  varchar(20)
    as
    begin
    declare @s varchar(20)
    select @s=isnull(@s+',','')+cname from tbs where id=@i
    return @s
    end
    go select a.id,a.iQuantity,b.cname,b.already,remaining=a.iQuantity-b.already
    from ta a
    join (
    select id,Already=sum(iQuantity),cname=dbo.f_str(id) 
    from tbs group by id
     ) b
    on a.id=b.id 
    id          iQuantity   cname                already     remaining
    ----------- ----------- -------------------- ----------- -----------
    1           100         A,C,F                30          70
    2           130         B,F                  23          107(2 行受影响)