create table test 

id  nvarchar(10), 
name nvarchar(20),
code  nvarchar(100)) 
insert into test select '01','a1' ,'1817A0Y003.1'
insert into test select '02','a2' ,'1817A0Y003.2.1'
insert into test select '03','a9' ,'1817A0Y003.2.2'
insert into test select '07','a15' ,'1817A0Y003.3'
insert into test select '05','a18' ,'1817A0Y003.4.1.2.1'
insert into test select '04','a8' ,'1817A0Y003.4.1.2.2'
insert into test select '010','a55' ,'1817A0Y003.4.1'
insert into test select '012','a25' ,'1817A0Y003.4.3.1'
insert into test select '017','a14' ,'1817A0Y003.4.5'
insert into test select '027','a24' ,'1817A0Y003.4.4'
insert into test select '0107','a104' ,'1817A0Y003.14.5'
insert into test select '0207','a204' ,'1817A0Y003.14.4'
/* 
要得到这样的报表: 
id    name      code 
01    a1        1817A0Y003.1
02    a2        1817A0Y003.2.1        
03    a9        1817A0Y003.2.2       
07    a15        1817A0Y003.3 
010    a55        1817A0Y003.4.1       
05    a18        1817A0Y003.4.1.2.1 
04    a8        1817A0Y003.4.1.2.2       
012    a25        1817A0Y003.4.3.1  
027    a24        1817A0Y003.4.4       
017    a14        1817A0Y003.4.5  
0207    a204        1817A0Y003.14.4       
0107    a104        1817A0Y003.14.5  
*/ 
code的可能格式:****.数字.数字.数字.数字…… (****长度不定,但一定相同。【.数字】循环次数不定,像树一样)
MS SQLServer 2000

解决方案 »

  1.   

    *
    标题:查询各节点的父路径函数
    作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开)  
    时间:2008-05-12
    地点:广东深圳
    *//*
    原始数据及要求结果如下:
    --食品 
      --水果 
        --香蕉 
        --苹果    
      --蔬菜 
        --青菜
    id          pid         name                 
    ----------- ----------- -------------------- 
    1           0           食品
    2           1           水果
    3           1           蔬菜
    4           2           香蕉
    5           2           苹果
    6           3           青菜要求得到各节点的父路径即如下结果:
    id  pid name  路径                         
    --- --- ----- ---------------
    1   0   食品  食品
    2   1   水果  食品,水果
    3   1   蔬菜  食品,蔬菜
    4   2   香蕉  食品,水果,香蕉
    5   2   苹果  食品,水果,苹果
    6   3   青菜  食品,蔬菜,青菜 
    */create table tb (id int , pid int , name nvarchar(20)) 
    insert into tb values(1 , 0 , '食品')
    insert into tb values(2 , 1 , '水果')
    insert into tb values(3 , 1 , '蔬菜')
    insert into tb values(4 , 2 , '香蕉')
    insert into tb values(5 , 2 , '苹果')
    insert into tb values(6 , 3 , '青菜')
    go--查询各节点的父路径函数
    create function f_pid(@id int) returns varchar(100)
    as
    begin
      declare @re_str as varchar(100)
      set @re_str = ''
      select @re_str = name from tb where id = @id
      while exists (select 1 from tb where id = @id and pid <> 0)
        begin
          select @id = b.id , @re_str = b.name + ',' + @re_str from tb a , tb b where a.id = @id and a.pid = b.id
        end
      return @re_str
    end
    goselect * , dbo.f_pid(id) 路径 from tb order by iddrop table tb
    drop function f_pidSQL code
    /*
    标题:查询所有节点及其所有子节点的函数
    作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开) 
    时间:2009-04-12
    地点:广东深圳
    */--生成测试数据 
    create table tb(id varchar(10),pid varchar(10)) 
    insert into tb select 'a', null 
    insert into tb select 'b', 'a' 
    insert into tb select 'c', 'a' 
    insert into tb select 'd', 'b' 
    insert into tb select 'e', 'b' 
    insert into tb select 'f', 'c' 
    insert into tb select 'g', 'c' 
    go --创建用户定义函数 
    create function f_getchild(@id varchar(10)) returns varchar(8000) 
    as 
    begin 
      declare @i int , @ret varchar(8000) 
      declare @t table(id varchar(10) , pid varchar(10) , level int) 
      set @i = 1 
      insert into @t select id , pid , @i from tb where id = @id 
      while @@rowcount <> 0 
      begin 
        set @i = @i + 1 
        insert into @t select a.id , a.pid , @i from tb a , @t b where a.pid = b.id and b.level = @i - 1
      end 
      select @ret = isnull(@ret , '') + id + ',' from @t 
      return left(@ret , len(@ret) - 1)
    end 
    go --执行查询 
    select id , children = isnull(dbo.f_getchild(id) , '') from tb group by id
    go --输出结果 
    /* 
    id         children     
    ---------- -------------
    a          a,b,c,d,e,f,g
    b          b,d,e
    c          c,f,g
    d          d
    e          e
    f          f
    g          g(所影响的行数为 7 行)*/ --删除测试数据 
    drop function f_getchild 
    drop table tb
      

  2.   

    drop table test
    create table test 

    id  nvarchar(10), 
    name nvarchar(20), 
    code  nvarchar(100) ) 
    insert into test select '01','a1' ,'1817A0Y003.1' 
    insert into test select '02','a2' ,'1817A0Y003.2.1' 
    insert into test select '03','a9' ,'1817A0Y003.2.2' 
    insert into test select '07','a15' ,'1817A0Y003.3' 
    insert into test select '05','a18' ,'1817A0Y003.4.1.2.1' 
    insert into test select '04','a8' ,'1817A0Y003.4.1.2.2' 
    insert into test select '010','a55' ,'1817A0Y003.4.1' 
    insert into test select '012','a25' ,'1817A0Y003.4.3.1' 
    insert into test select '017','a14' ,'1817A0Y003.4.5' 
    insert into test select '027','a24' ,'1817A0Y003.4.4' 
    insert into test select '0107','a104' ,'1817A0Y003.14.5' 
    insert into test select '0207','a204' ,'1817A0Y003.14.4' 
    --函数
    create function dbo.getcode(@code varchar(8000))
    returns varchar(8000)
    as
    begin
    declare @str varchar(8000)
    select @str=isnull(@str+'.','')+right('0000'+code,4)
    from 
    (select number,code=substring(@code,number,charindex('.',@code+'.',number)- number)
    from master..spt_values
    where type='p' 
    and substring('.'+@code,number,1)='.') t
    where number <> 1
    return @str
    end--查询
    select * from test 
    order by dbo.getcode(code)
    --结果
    -----------------------------------------
    01 a1 1817A0Y003.1
    02 a2 1817A0Y003.2.1
    03 a9 1817A0Y003.2.2
    07 a15 1817A0Y003.3
    010 a55 1817A0Y003.4.1
    05 a18 1817A0Y003.4.1.2.1
    04 a8 1817A0Y003.4.1.2.2
    012 a25 1817A0Y003.4.3.1
    027 a24 1817A0Y003.4.4
    017 a14 1817A0Y003.4.5
    0207 a204 1817A0Y003.14.4
    0107 a104 1817A0Y003.14.5
      

  3.   


    drop table testcreate table test 

    id  nvarchar(10), 
    name nvarchar(20), 
    code  nvarchar(100) ) 
    insert into test select '01','a1' ,'1817A0Y003.1' 
    insert into test select '02','a2' ,'1817A0Y003.2.1' 
    insert into test select '03','a9' ,'1817A0Y003.2.2' 
    insert into test select '07','a15' ,'1817A0Y003.3' 
    insert into test select '05','a18' ,'1817A0Y003.4.1.2.1' 
    insert into test select '04','a8' ,'1817A0Y003.4.1.2.2' 
    insert into test select '010','a55' ,'1817A0Y003.4.1' 
    insert into test select '012','a25' ,'1817A0Y003.4.3.1' 
    insert into test select '017','a14' ,'1817A0Y003.4.5' 
    insert into test select '027','a24' ,'1817A0Y003.4.4' 
    insert into test select '0107','a104' ,'1817A0Y003.14.5' 
    insert into test select '0207','a204' ,'1817A0Y003.14.4' 
    select * from testdeclare @i int,@max int
    declare @a varchar(10)
    declare @sql varchar(100)
    declare @sql2 varchar(100)
    set @sql=''
    set @sql2=''
    set @i=1
    select @max=max(dbo.Spit(code,'.')) from test
    while @i<=@max
    begin
    select @a='a'+cast(@i as varchar(10))
    set @sql='alter table test add '+ @a +' int'
    set @sql2='update test set '+ @a +'=0'
    exec(@sql)
    exec(@sql2)
    set @sql=''
    set @i=@i+1
    end
    declare @a varchar(100)
    declare cur_test cursor for select code from test
    open  cur_test
    fetch next from cur_test into @a
    while(@@fetch_status=0)
    begin
        declare @i int,@max int
    declare @b varchar(10)
    declare @value varchar(10)
    select @max=max(dbo.Spit(code,'.')) from test where code=@a
    set @i=1
    declare @sql varchar(8000)
    select @value=''''+substring(code,charindex('.',code)+1,len(code)-(charindex('.',code))+2)+'''' from test where code=@a
    while @i<=@max
    begin
    set @sql=''
    select @b='a'+cast(@i as varchar(10))
    --set @sql='update test set '+ @b +'=left('+@value+',charindex(''.'','+@value+')-1) where a='+@a
    if charindex('.',@value)>0
    begin
    set @sql='update test set '+ @b +'=left('+ @value + ',charindex(''.'','+ @value +')-1) where code='''+ @a + ''''
    end
    else
    begin
    set @sql='update test set '+ @b +'='+ @value +' where code='''+ @a + ''''
    end
    exec(@sql)
    set @i=@i+1
    select @value=''''+substring(@value,charindex('.',@value)+1,len(@value)-charindex('.',@value))
    end
        fetch next from cur_test into @a
    end
    close  cur_test
    deallocate  cur_testselect id,name,code from test order by a1,a2,a3,a4-----------------------01 a1 1817A0Y003.1
    02 a2 1817A0Y003.2.1
    03 a9 1817A0Y003.2.2
    07 a15 1817A0Y003.3
    010 a55 1817A0Y003.4.1
    05 a18 1817A0Y003.4.1.2.1
    04 a8 1817A0Y003.4.1.2.2
    012 a25 1817A0Y003.4.3.1
    027 a24 1817A0Y003.4.4
    017 a14 1817A0Y003.4.5
    0207 a204 1817A0Y003.14.4
    0107 a104 1817A0Y003.14.5
      

  4.   

    学习4楼的写法,可以写成这样
    select * from test
    order by
    (
    select right('0000'+code,4) as [text()] from (
    select number,code=substring(code,number,charindex('.',code+'.',number)- number)
    from master..spt_values
    where type='p' 
    and substring('.'+code,number,1)='.'  and number<>1) t for xml path('') 
    )