当@n=6时,原始数据如下:
a           b           
----------- ----------- 
1           1
2           3
3           5
4           7
5           9
6           11
7           2
8           4
9           6
10          8
11          10
12          12第1条记录 b=1 查找a=1的记录 还是第1条记录 构成一个环,输出 
id     c
1      1
第2条记录 b=2 查找a=2的记录,第3条a=3 b=5
      查找a=5 的记录,第5条a=5 b=9
      查找a=9 的记录,第9条a=9 b=6
      ...
      查找a=7 的记录,第7条a=7 b=2
      又回到了2   加上前面的输出
id     c
1      1
2      2,3,5,9,6,11,10,8,4,7   
.....

解决方案 »

  1.   

    第2条记录   b=2   查找a=2的记录,第3条a=3   b=5 
    -----
    第2条记录   a=2 b=3   查找a=3的记录,第3条a=3   b=5 
      

  2.   

    这不就像bom一样找路径? 只不过不是以 什么如果还有子即退出,而是以子的b=根的b为终结.是这个意思吗?是的话就不写了.
      

  3.   

    /*
    create  table t(a int,b int)
    declare @n int
    set @n = 4
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert t select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update t set b = 2*@n -1 where b = 0
    update t set b = 2*@n    where a = 2*@n
    select * from t*/declare @T table(ID int,col nvarchar(1000))
    declare @i int,@j int
    set @i=1
    while @i!>4
    begin
    select @j=b from T where a=@i
    if @i=1
    insert @T values(@i,@j)
    else if @i=2
    insert @t values(@i,rtrim(@i)+','+rtrim(@j))
    else if @i=3
    begin
    select @j=b from T where a=@i+1
    insert @t values(@i,rtrim(@i+1)+','+rtrim(@j))
    end
    else 
    begin
    select top 1 @j=b from T order by b desc
    insert @t values(@i,rtrim(@j)+','+rtrim(@j))
    end
    set @j=(select b from t where a=@j)
    while @j<>@i and not exists(select 1 from @T where ID=@i and charindex(','+rtrim(@j)+',',','+col+',')>0)
    begin
    --print rtrim(@i)+'i'
    print @j
    update a
    set col=a.col+','+rtrim(@j)
    from 
    @T a
    where
    a.ID=@i 
    set @j=(select b from t where a=@j)
    end 
    set @i=@i+1endselect * from @t
      

  4.   


    --生成测试数据
    create table BOM(a int,b int )go
    declare @n int
    set @n = 5
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert BOM select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update BOM set b = 2*@n -1 where b = 0
    update BOM set b = 2*@n    where a = 2*@n
    select * from BOM
    /*a           b           
    ----------- ----------- 
    1           1
    2           3
    3           5
    4           7
    5           9
    6           2
    7           4
    8           6
    9           8
    10          10(所影响的行数为 10 行)
    */go--创建用户定义函数,每个子节点de父节点的信息
    create function f_getChild(@ID int)
    returns varchar(100)
    as
    begin
        declare @i int
        declare @oldid int
        declare @ret varchar(100)
        set @oldid = @id
        declare @t table(ID VARCHAR(10),PID VARCHAR(10),Level INT)
        set @i = 1
        insert into @t select a,b,@i from BOM where A = @ID    
        while @@rowcount<>0
        begin
            set @i = @i + 1
            
            insert into @t 
            select 
                a.a,a.b,@i 
            from 
                BOM a,@t b 
            where 
                a.b=b.ID and b.Level = @i-1 and a.a <> @oldid
       
        end
        select @ret=','+rtrim(id)+isnull(@ret,'')
        from @t order by level
        
        set @ret=stuff(@ret,1,1,'')
        select @ret = @ret + '--' + min(id) from @t
        return @ret
    end
    go--执行查询
    select a,substring(c,1,charindex( '--',c)-1) as c
    from (
    select a,isnull(dbo.f_getchild(a),'') as c
    from bom) T
    where a = substring(c,charindex('--',c)+2,100)
    go
    --输出结果
    /*
    a           c               
    ----------- -----------------------
    1           1
    2           3,5,9,8,6,2
    4           7,4
    10          10(所影响的行数为 4 行)
    */--删除测试数据
    drop function f_getChild
    drop table BOM
    go
      

  5.   


    /*
    create  table t(a int,b int)
    declare @n int
    set @n = 4
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert t select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update t set b = 2*@n -1 where b = 0
    update t set b = 2*@n    where a = 2*@n
    select * from t*/declare @T table(ID int,col nvarchar(1000))
    declare @i int,@j int
    set @i=1
    while @i!>4
    begin
    select @j=b from T where a=@i
    if @i=1
        insert @T values(@i,@j)
    else if @i=2
        insert @t values(@i,rtrim(@i)+','+rtrim(@j))
    else if @i=3
        begin
            select @j=b from T where a=@i+1
            insert @t values(@i,rtrim(@i+1)+','+rtrim(@j))
        end
    else 
    begin
        select top 1 @j=b from T order by b desc
        insert @t values(@i,rtrim(@j)+','+rtrim(@j))
    end
    set @j=(select b from t where a=@j)
    while @j<>@i and not exists(select 1 from @T where ID=@i and charindex(','+rtrim(@j)+',',','+col+',')>0)
        begin    
        --print rtrim(@i)+'i'
       -- print @j    
            update a
            set col=a.col+','+rtrim(@j)
            from 
                @T a
            where
                a.ID=@i     
            set @j=(select b from t where a=@j)
        end 
    set @i=@i+1endselect * from @t
    --结果:
    /*
    1           1
    2           2,3,5
    3           4,7,6
    4           8,8
    */--原始数据
    /*
    create  table t(a int,b int)
    declare @n int
    set @n = 5
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert t select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update t set b = 2*@n -1 where b = 0
    update t set b = 2*@n    where a = 2*@n
    select * from t*/--结果
    /*
    1           1
    2           2,3,5,9,8,6
    3           4,7
    4           10,10
    */
      

  6.   

    随便写了一下.算法没细看,应该是差了一点.
    declare @t table(a int,b int)
    declare @n int
    set @n = 6
    declare @i int
    select @i = 1while @i <=2*@n
    begin
    insert @t select @i,(2*@i-1)%(2*@n-1)
    set @i = @i+1
    endupdate @t set b = 2*@n -1 where b = 0
    update @t set b = 2*@n    where a = 2*@n
    select * from @tdeclare @r table(b int,path varchar(1000))
    declare @curA int,@curB int,@cur int,@s varchar(1000),@tmpB int,@inner bit,@thisB int
    select @cur=max(a),@i=0 from @tset @inner = 1
    while @inner = 1 and (select count(*) from @r)<@n
    begin
    set @curB = null
    select top 1 @curB = b from @t a where b not in(select b from @r) if @curB is null
    set @inner = 0
    else begin
    select @i = 0,@thisB = @curB
    select @s=null,@tmpB=@curB,@s=@curB while @i<@cur
    begin



    select @curA=b.a,@curB=b.b from @t b
    inner join @t a
    on a.b=b.a
    where a.b=@tmpB
    select @s=@s + ',' + rtrim(@curB)
    if @thisB = @curB
    begin
    set @i=100000
    insert @r select @curB,@s
    end
    else
    select @i=@i+1,@tmpB = @curB

    end
    end
    endselect * from @r
    /*
    1 1,1
    3 3,5,9,6,11,10,8,4,7,2,3
    5 5,9,6,11,10,8,4,7,2,3,5
    7 7,2,3,5,9,6,11,10,8,4,7
    9 9,6,11,10,8,4,7,2,3,5,9
    11 11,10,8,4,7,2,3,5,9,6,11
    2 2,3,5,9,6,11,10,8,4,7,2
    4 4,7,2,3,5,9,6,11,10,8,4
    6 6,11,10,8,4,7,2,3,5,9,6
    8 8,4,7,2,3,5,9,6,11,10,8
    10 10,8,4,7,2,3,5,9,6,11,10*/
      

  7.   

    跟楼主要的结果稍有点不同. 改一下,就一样了.
    declare @t table(a int,b int)
    declare @n int
    set @n = 6
    declare @i int
    select @i = 1while @i <=2*@n
    begin
    insert @t select @i,(2*@i-1)%(2*@n-1)
    set @i = @i+1
    endupdate @t set b = 2*@n -1 where b = 0
    update @t set b = 2*@n    where a = 2*@n
    select * from @tdeclare @r table(b int,path varchar(1000))
    declare @curA int,@curB int,@cur int,@s varchar(1000),@tmpB int,@inner bit,@thisB int
    select @cur=max(a),@i=0 from @tset @inner = 1
    while @inner = 1 --and (select count(*) from @r)<@n
    begin
    set @curB = null
    select top 1 @curB = b from @t a where b not in(select b from @r) if @curB is null
    set @inner = 0
    else begin
    select @i = 0,@thisB = @curB
    select @tmpB=@curB,@s=null while @i<@cur
    begin



    select @curA=b.a,@curB=b.b from @t b
    inner join @t a
    on a.b=b.a
    where a.b=@tmpB
    select @s=isnull(@s+',','') + rtrim(@curA)
    if @thisB = @curB
    begin
    set @i=100000
    insert @r select @curB,@s
    end
    else
    select @i=@i+1,@tmpB = @curB

    end
    end
    endselect * from @r order by b
    /*
    1 1
    2 2,3,5,9,6,11,10,8,4,7
    3 3,5,9,6,11,10,8,4,7,2
    4 4,7,2,3,5,9,6,11,10,8
    5 5,9,6,11,10,8,4,7,2,3
    6 6,11,10,8,4,7,2,3,5,9
    7 7,2,3,5,9,6,11,10,8,4
    8 8,4,7,2,3,5,9,6,11,10
    9 9,6,11,10,8,4,7,2,3,5
    10 10,8,4,7,2,3,5,9,6,11
    11 11,10,8,4,7,2,3,5,9,6
    12 12
    */
      

  8.   

    --生成测试数据
    create table BOM(a int,b int )go
    declare @n int
    set @n = 5
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert BOM select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update BOM set b = 2*@n -1 where b = 0
    update BOM set b = 2*@n    where a = 2*@n
    select * from BOM
    /*a           b           
    ----------- ----------- 
    1           1
    2           3
    3           5
    4           7
    5           9
    6           2
    7           4
    8           6
    9           8
    10          10(所影响的行数为 10 行)
    */go--创建用户定义函数,每个子节点de父节点的信息
    create function f_getChild(@ID int)
    returns varchar(100)
    as
    begin
        declare @i int
        declare @oldid int
        declare @ret varchar(100)
        set @oldid = @id
        declare @t table(ID VARCHAR(10),PID VARCHAR(10),Level INT)
        set @i = 1
        insert into @t select a,b,@i from BOM where A = @ID    
        while @@rowcount<>0
        begin
            set @i = @i + 1
            
            insert into @t 
            select 
                a.a,a.b,@i 
            from 
                BOM a,@t b 
            where 
                a.b=b.ID and b.Level = @i-1 and a.a <> @oldid
       
        end
        select @ret=','+rtrim(id)+isnull(@ret,'')
        from @t order by level
        
        set @ret=stuff(@ret,1,1,'')
        select @ret = @ret + '--' + min(id) from @t
        return @ret
    end
    go--执行查询
    select a,substring(c,1,charindex( '--',c)-1) as c into #
    from (
        select a,isnull(dbo.f_getchild(a),'') as c
        from bom) T
    where a = substring(c,charindex('--',c)+2,100)select a=(select count(1)+ 1 from # where a <d.a),c
    from # d
    go
    --输出结果
    /*
    a           c               
    ----------- -----------------------
    1           1
    2           3,5,9,8,6,2
    3           7,4
    4           10(所影响的行数为 4 行)
    */--删除测试数据
    drop function f_getChild
    drop table BOM,#
    go
      

  9.   

    还是要感谢大家,如果是简单的BOM肯定不会问大家,注意要严格按照显示结果的要求,当然,者只是问题的第一步,目的是为了让大家能够更好的了解题目,我下面的回复会说出问题的第二个部分,简直是超级难题,我已经花费了2周的时间,但毫无进展,甚至没有半点头绪。
    to happyflystone : 结果顺序不对,第一个数字应该为最小的。
    2    3,5,9,8,6,2 应为:2,3,5,9,8,6
    3    7,4         应为:4,7to roy_88 :n为不固定的。to fcuandy :差之毫厘,失之千里,关键就在这。
      

  10.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 4 时,结果:1,2,12
    上面的都不能,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
      

  11.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 4 时,结果:1,2,12
    上面的都不能,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
      

  12.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 4 时,结果:1,2,12
    上面的都不能,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
      

  13.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 4 时,结果:1,2,12
    上面的都不能,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  14.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 4 时,结果:1,2,12
    上面的都不能,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  15.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 4 时,结果:1,2,12
    上面的都不难,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  16.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 6 时,结果:1,2,12
    上面的都不难,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  17.   

    happyflystone   的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 6 时,结果:1,2,12
    上面的都不难,难就难在有一个条件,只给了一个@n,并没有给数据表。
    而且@n = 1亿,现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  18.   

    happyflystone (12楼)  的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 6 时,结果:1,2,12现在我们明白,给定一个@n,就能得到一个串,而且只要@n相同,串就相同,@n不同,串可能相同,也可能不同,
    与其它因素,只要@n给定了,就能得到一个串。
    上面的都不难,
    现在的问题是,只给了一个@n,并没有给数据表,而且@n = 1亿,求这个串,
    现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  19.   

    32楼有个错误。happyflystone (12楼)  的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 6 时,结果:1,2,12现在我们明白,给定一个@n,就能得到一个串,而且只要@n相同,串就相同,@n不同,也不同,与其它因素,只要@n给定了,就能得到一个串。
    上面的都不难,
    现在的问题是,只给了一个@n,并没有给数据表,而且@n = 1亿,求这个串,
    现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  20.   

    32楼有个错误。happyflystone (12楼)  的代码略作修改就可以达到要求了,
    在set @oldid = @id前面加一句
    select @id = a from bom where b =@id就可以了。
    问题的第二步是,只要求显示一个串,这个串由结果集中C字段的首个数字构成。
    例如:
    当@n = 4 时,结果:1,2,4,8
    当@n = 5 时,结果:1,2,4,10
    当@n = 6 时,结果:1,2,12现在我们明白,给定一个@n,就能得到一个串,而且只要@n相同,串就相同,@n不同,串也不同,与其它因素,只要@n给定了,就能得到一个串。
    上面的都不难,
    现在的问题是,只给了一个@n,并没有给数据表,而且@n = 1亿,求这个串,
    现在不太可能通过创建表来计算数据了。有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
    有结果立即结贴,分不够,另开贴加分。
      

  21.   

    --生成测试数据
    create table BOM(a int,b int )go
    declare @n int
    set @n = 4
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert BOM select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update BOM set b = 2*@n -1 where b = 0
    update BOM set b = 2*@n    where a = 2*@n
    select * from BOM
    go--创建用户定义函数,每个子节点de父节点的信息
    create function f_getChild(@ID int)
    returns varchar(100)
    as
    begin
        declare @i int
        declare @oldid int
        declare @ret varchar(100)
        select   @id   =   a   from   bom   where   b   =@id
        set @oldid = @id
        declare @t table(ID VARCHAR(10),PID VARCHAR(10),Level INT)
        set @i = 1
        insert into @t select a,b,@i from BOM where A = @ID    
        while @@rowcount<>0
        begin
            set @i = @i + 1
            
            insert into @t 
            select 
                a.a,a.b,@i 
            from 
                BOM a,@t b 
            where 
                a.b=b.ID and b.Level = @i-1 and a.a <> @oldid
       
        end
        select @ret=','+rtrim(id)+isnull(@ret,'')
        from @t order by level
        
        set @ret=stuff(@ret,1,1,'')
        select @ret = @ret + '--' + min(id) from @t
        return @ret
    end
    go--执行查询
    declare @s varchar(100)
    set @s = ''
    select @s = @s +','+ ltrim(a)
    from (
    select a 
    from (
        select a,isnull(dbo.f_getchild(a),'') as c
        from bom) T
    where a = substring(c,charindex('--',c)+2,100)) t
    select @s= stuff(@s,1,1,'')
    select @s
    go
    --输出结果
    /*
    n = 4---------------------------------------------------------------------------------------------------- 
    1,2,4,8n = 5
    ---------------------------------------------------------------------------------------------------- 
    1,2,4,10n = 6
    ---------------------------------------------------------------------------------------------------- 
    1,10,12
    */--删除测试数据
    drop function f_getChild
    drop table BOM
    go
      

  22.   

    --生成测试数据
    create table BOM(a int,b int )go
    declare @n int
    set @n = 4
    declare @i int
    select @i = 1
    while @i <=2*@n
    begin  
     insert BOM select @i,(2*@i-1)%(2*@n-1)
     set @i = @i+1
    end
    update BOM set b = 2*@n -1 where b = 0
    update BOM set b = 2*@n    where a = 2*@ngo--创建用户定义函数,每个子节点de父节点的信息create table tt(a int, b varchar(100))
    go
    create function f_getChild(@ID int)
    returns int
    as
    begin
        declare @i int
        declare @oldid int
        declare @ret varchar(100)
        select   @id   =   a   from   bom   where   b   =@id
        set @oldid = @id
        declare @t table(ID VARCHAR(10),PID VARCHAR(10),Level INT)
        set @i = 1
        insert into @t select a,b,@i from BOM where A = @ID    
        while @@rowcount<>0
        begin
            set @i = @i + 1
            
            insert into @t 
            select 
                a.a,a.b,@i 
            from 
                BOM a,@t b 
            where 
                a.b=b.ID and b.Level = @i-1 and a.a <> @oldid
       
        end
        select @ret=','+rtrim(id)+isnull(@ret,'')
        from @t order by convert(int,id) desc
        
        set @ret=stuff(@ret,1,1,'')
        select @ret = min(cast(id as int)) from @t
        return @ret
    end
    go--执行查询
    declare @s varchar(100)
    set @s = ''
    select @s = @s +','+ ltrim(c)
    from ( select distinct isnull(dbo.f_getchild(a),'') as c
       from bom ) t
    order by c
    select @s= stuff(@s,1,1,'')
    select @s
    go
    --输出结果
    /*
    n = 4---------------------------------------------------------------------------------------------------- 
    1,2,4,8n = 5
    ---------------------------------------------------------------------------------------------------- 
    1,2,4,10n = 6
    ---------------------------------------------------------------------------------------------------- 
    1,2,12
    */--删除测试数据
    drop function f_getChild
    drop table BOM,tt
    go
      

  23.   

    declare @t table(a int,b int)
    declare @n int
    set @n = 5
    declare @i int
    select @i = 1
    while @i <=@n
    begin  
     insert @t select @i,2*@i-1
     set @i = @i+1
    end
    insert @t select a+@n,b+1 from @t;WITH CTE (rootnode, childnode)
    AS
    (
        select a,b
    from @t where a<=@n
    union all
    SELECT rootnode,b
        FROM @t t inner join cte on t.a=cte.childnode
    where rootnode<>childnode
    )
    select * from cte
    order by rootnode,case when rootnode=childnode then 0 else 1 end;
    /*
    rootnode    childnode
    ----------- -----------
    1           1
    2           2
    2           3
    2           5
    2           9
    2           8
    2           6
    3           3
    3           9
    3           8
    3           6
    3           2
    3           5
    4           4
    4           7
    5           5
    5           9
    5           8
    5           6
    5           2
    5           3(21 row(s) affected)
    */--接下来该怎么做楼主一定没问题
      

  24.   

    跟着结果比较起来, 有点不对.是取a,还是取b,是按a来匹配还b,我已经有点混了.
      

  25.   

    当@n=6时,原始数据如下: 
    a                       b                       
    -----------   -----------   
    1                       1 
    2                       3 
    3                       5 
    4                       7 
    5                       9 
    6                       11 
    7                       2 
    8                       4 
    9                       6 
    10                     8 
    11                     10 
    12                     12 第1条记录   b=1   查找a=1的记录   还是第1条记录   构成一个环,输出   
    id           c 
    1             1 
    第2条记录   b=2   查找a=2的记录,第3条a=3   b=5 
                查找a=5   的记录,第5条a=5   b=9 
                查找a=9   的记录,第9条a=9   b=6 
                ... 
                查找a=7   的记录,第7条a=7   b=2 
                又回到了2       加上前面的输出 
    id           c 
    1             1 
    2             2,3,5,9,6,11,10,8,4,7       
    .....
    ----------------------------------------第二条记录,明明b=3什么说b=2?
      

  26.   

    搂主玩死我的电脑了--数据分类函数
    create function fn_分类函数(
    @n int,
    @x int)
    returns int
    as
    begin
    declare @t table (a int)
         insert @t values(@x)
    declare @i int
    set @i=case when @x % 2 =0 then @n+@x/2 else (@x+1)/2 end
    while @i<>@x
    begin
    insert @t values(@i)
    set @i=case when @i% 2 =0 then @n+@i/2 else (@i+1)/2 end
    end
    return (select min(a) from @t)
    end
    go--目的函数
    create function fn_目的函数(
    @n int)
    returns varchar(2000)
    as
    begin
    declare @r varchar(2000)
    set @r=''
    declare @t table (a int)
    declare @i int
    set @i = 1
    while @i <=2*@n
    begin  
      insert @t values( @i)
      set @i = @i+1
    end
    select @r=@r+','+cast(x as varchar) from (
    select distinct x=dbo.fn_分类函数(@n,a) from @t
    ) as t
    return stuff(@r,1,1,'')
    end--测试
    select dbo.fn_目的函数(4)
    --
    1,2,4,8select dbo.fn_目的函数(5)
    --
    1,2,4,10select dbo.fn_目的函数(6)
    --
    1,2,12select dbo.fn_目的函数(50)
    --
    1,2,4,6,10,12,16,34,100select dbo.fn_目的函数(100)
    --
    1,2,4,200--更大的数据需要优化算法
      

  27.   

    create table #t(a int identity, b int)
    create table #(a int, b int)
    create table #r(a int)
    declare @n int
    set @n=10000
    insert into #t select top (@n) null from sys.sysobjects a,sys.sysobjects b,sys.sysobjects c,sys.sysobjects d
    insert into # select a,2*a-1 b from #t 
    insert into # select a+@n,2*a from #declare @i int
    select @i=(select top 1 a from #)
    while @@rowcount>0
    begin
    insert into #r select @i;
    WITH CTE (rootnode, childnode)
    AS
    (
    select a,b
    from # where a=@i
    union all
    SELECT rootnode,b
    FROM # t inner join cte on t.a=cte.childnode
    where rootnode<>childnode
    )
    delete t from # t inner join cte on t.a=cte.childnode
    OPTION (MAXRECURSION 0); select top 1 @i=a from #
    end
    declare @s varchar(max)
    set @s=''
    select @s=@s+','+rtrim(a) from #r
    select @s=rtrim(@n)+':  '+stuff(@s,1,1,'')
    print @sdrop table #r,#,#t/*
    10000:  1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,54,56,58,62,64,68,70,72,76,78,80,82,84,86,88,90,92,94,96,98,102,104,106,108,110,112,116,118,120,122,124,126,130,132,134,136,140,142,144,146,148,152,156,160,162,164,166,168,170,172,180,182,184,190,192,194,200,202,208,210,212,214,218,222,228,230,232,240,242,244,246,248,254,260,262,266,276,280,282,284,286,290,292,300,302,304,306,328,336,342,346,350,352,356,360,368,370,374,376,386,388,390,398,404,406,408,410,416,426,430,432,436,442,454,464,466,468,476,490,492,494,498,502,510,516,522,528,534,536,540,542,544,560,564,572,574,584,594,596,608,654,656,672,680,682,690,696,728,742,760,764,796,816,826,878,904,906,1054,1094,1108,1112,1156,1206,1360,1376,1464,1630,1690,1780,1946,2858,3582,8572,20000
    */
      

  28.   

    sql没有数组的概念,只能用表实现。这个数学问题放到c 或vb中应该快的多。
    在sql中的算法我继续想。头痛...
      

  29.   

    --用存储过程实现,速度快些
    --分类过程
    create proc pr_分类过程 
    @N int,
    @i int,
    @tabnum int output
    as
    set nocount on
    declare @TabName varchar(100)
    set @TabName='##t'+Cast(@tabnum as nvarchar)set @tabnum=@tabnum+1declare @sql nvarchar(4000)
    declare @r int
    declare @ic varchar(20)
    declare @nc varchar(20)
    set @ic=Cast(@i as varchar)
    set @nc=Cast(@n as varchar)
    set @sql=N'Create table '+@TabName+' (a int)
    declare @x int
    declare @n int
    set @x='+@ic+'
    set @n='+@nc+'
        insert '+@TabName+' values(@x)
    declare @i int
    set @i=case when @x % 2 =0 then @n+@x/2 else (@x+1)/2 end
    while @i<>@x
    begin
    insert '+@TabName+' values(@i)
    set @i=case when @i% 2 =0 then @n+@i/2 else (@i+1)/2 end
    end
    select @r=min(a) from '+@TabNameexec sp_executesql @sql,N'@r int output',@r output
    return @r
    go
    --目的过程
    alter proc pr_目的过程
    @n int
    as
    set nocount on
    declare @tabnum int
    set @tabnum=1declare @i int
    set @i=1declare @r varchar(2000)
    set @r=''declare @j int
    declare @sql Nvarchar(2000)
    declare @b bit
    declare @ri intwhile @i<=2*@n
    begin
    LabBeg:
    set @j=1
    while @j<@tabnum
    begin
    set @sql=N'if exists (select 1 from ##t'+cast(@j as nvarchar)+' where a='+cast(@i as nvarchar)+') select @e=1 else select @e=0'
    exec sp_executesql @sql,N'@e bit output',@b output
    if @b=1 --Next
    begin
    set @i=@i+1
    goto LabBeg
    end
    set @j=@j+1
    end
    exec @ri=pr_分类过程 @N,@i,@tabnum output
    set @r=@r+','+cast(@ri as varchar)
    set @i=@i+1
    endset @r=stuff(@r,1,1,'')
    select @r as Resultset @i=1
    while @i<@tabnum
    begin
    set @sql=N'drop table ##t'+Cast(@i as nvarchar)
    exec(@sql)
    set @i=@i+1
    endgo
    exec pr_目的过程 4
    --
    1,2,4,8exec pr_目的过程 5
    --
    1,2,4,10exec pr_目的过程 6
    --
    1,2,12exec pr_目的过程 50
    --
    1,2,4,6,10,12,16,34,100             --2秒exec pr_目的过程 100
    --
    1,2,4,200 -- 3秒
    exec pr_目的过程 1000
    --
    1,2,4,6,8,10,16,2000 -- 1分09秒--更大数据不敢试了
      

  30.   

    我要的不是以下结果,我要的是@n = 1亿的结果。
    create  function f_geth(@n int)
    returns varchar(8000)
    as
    begin
        declare @t table(a int)
        declare @s varchar(8000)
        declare @i int,@id int,@c int
        set @s = ''
        set @i = 2
        set @c = 2*@n -1
        while @i <=@c
         begin
          if not exists(select 1 from @t where a= @i)
           begin
            set @s = @s +','+rtrim(@i/2)
            insert @t select @i
            set @id = (2*@i-1)%@c
            if @id = 0 set @id = @c
            while @i <> @id
             begin
              insert @t select @id
              set @id = (2*@id-1)%@c
              if @id = 0 set @id = @c
             end
           end
          set @i = @i +1
         end
        return stuff(@s,1,1,'')
    end
    GO
    执行
    select top 10 identity(int,1000,1) id,convert(varchar(8000),'') c into # from dbo.syscolumns
    update # set c = dbo.f_geth(id)
    select * from #
    drop table #
    在我的破本本上(512m,p4 1.1g)花了11S
    结果如下:
    /*
    id          c 
    ----------- -----------------------------------------------------------------------------------------------------------------------------------------------
    1000        1,2,3,4,5,8
    1001        1,2,3,4,8,12,15,16,35,44,58,73,218,334
    1002        1,2,3,4,5,9,18
    1003        1,2,3,4,5,6,7,8,9,10,201
    1004        1,2,3,5,7,8,10,12,14,15,20,23,29,35,41,44,59,86,112,335
    1005        1,2,3,4,6,11,18,21,25,39,62,74,144,431
    1006        1,2,3,4,7
    1007        1,2,3,4,5,6,7,9,10,11,12,13,14,16,17,19,20,21,25,28,29,31,35,37,41,43,54,55,57,60,62,75,92,104,115,153,336
    1008        1,2,3,4,5,6,7,8,10,12,13,15,16,18,19,20,21,22,24,25,27,28,29,30,31,33,35,38,39,42,46,47,52,55,59,72,78,86,90,98,109,150,163,171,202,228,358,488
    1009        1,2,3,5,7,9
    */