drop table # 
drop table #tmp_table 
--创造测试数据 
create table #(ID char(3),       ID2 int,      parent char(3)) 
insert # select '001',               1,             '000' 
insert # select '002',               2,             '001' 
insert # select '003',               3,             '002' 
insert # select '004',               4,             '003' 
insert # select '005',               1,             '000' select *,[lev]=cast(''as int) into #tmp_table from # where 1<>1 
declare @i int 
set @i=1 
insert #tmp_table select ID,ID2,parent,@i from # where ID2=1--输入查询的参数 while @@rowcount>0 
begin 
    set @i=@i+1 
    insert #tmp_table select a.ID,a.ID2,a.parent,@i from # a join #tmp_table b on a.parent=b.ID and b.lev=@i-1 
end 
--测试 
select * from #tmp_table上面的数据得到
001 1 000 1
005 1 000 1
002 2 001 2
003 3 002 3
004 4 003 4
这是我期望的结果
可把测试数据
insert # select '005',               1,             '000' 
修改成
insert # select '005',               1,             '001' 得到的是
001 1 000 1
005 1 001 1   
002 2 001 2
005 1 001 2
003 3 002 3
004 4 003 4注意上面多了一行修改过的数据
我的问题是为什么会出现这种问题呢? 如何修改循环里的最后一个insert语句,使得不出现重复数据?

解决方案 »

  1.   

    我现在想了一个办法,就是检索前先去除多余的数据drop table # 
    drop table #tmp_table 
    --创造测试数据 
    create table #(ID char(3),       ID2 int,      parent char(3)) 
    insert # select '001',               1,             '000' 
    insert # select '002',               2,             '001' 
    insert # select '003',               3,             '002' 
    insert # select '004',               4,             '003' 
    insert # select '005',               1,             '001' 
    insert # select '006',               1,             '001' select *,[lev]=cast(''as int) into #tmp_table from # where 1<>1 
    declare @i int 
    set @i=1 
    insert #tmp_table select ID,ID2,parent,@i from # where ID2=1--输入查询的参数 while @@rowcount>0 
    begin 
        set @i=@i+1 
        insert #tmp_table select a.ID,a.ID2,a.parent,@i from # a join #tmp_table b on a.parent=b.ID and b.lev=@i-1 
    end 
    --测试 
    select * from #tmp_table
    delete   a   from   #tmp_table   a   
      where   exists(select   1   from    #tmp_table  where   ID=a.ID   and   parent=a.parent   and   lev<a.lev)select * from #tmp_table得到
    001 1 000 1
    005 1 001 1
    006 1 001 1
    002 2 001 2
    003 3 002 3
    004 4 003 4 
    但是这不是最好的办法, 如果能够在循环里就控制好根本不插入多余的行不是更好, 怎么做呢? 有人知道吗?
      

  2.   

    eg:declare  @a table(id int)
    insert into @a select 1 union all select 2
    declare  @b table (id int)
    insert into @b select 1 
    insert into @b select * from @a a where  not exists (select * from @b b where a.id=b.id)select * from @a 
    select * from @b
    您把这句子
    insert into @b select * from @a a where  not exists (select * from @b b where a.id=b.id)
    修改下看看
      

  3.   

    --> ADD: and a.ID<>b.ID
    insert #tmp_table select a.ID,a.ID2,a.parent,@i from # a join #tmp_table b on a.parent=b.ID and b.lev=@i-1 and a.ID<>b.ID
      

  4.   

        * wlzd3636
        * 菜菜鸟
        * 等 级:
    的方法是正确的。但你需求的结果可能不对。
      

  5.   

    --创造测试数据
    create table #(ID char(3), ID2 int, parent char(3))
    insert # select '001', 1, '000'
    insert # select '002', 2, '001'
    insert # select '003', 3, '002'
    insert # select '004', 4, '003'
    insert # select '005', 1, '001'
    insert # select '006', 1, '001'select *,[lev]=cast(''as int) into #tmp_table from # where 1<>1declare @i int 
    set @i=1 
    insert #tmp_table select ID,ID2,parent,@i from # where ID2=1--输入查询的参数 while @@rowcount> 0 
    begin 
    set @i=@i+1 
    insert #tmp_table select a.ID,a.ID2,a.parent,@i from # a join #tmp_table b on a.parent=b.ID and b.lev=@i-1 where not exists (select 1 from #tmp_table where ID = a.ID)
    end 
    --测试 
    select * from #tmp_table/*
    上面的数据得到
    001 1 000 1
    005 1 001 1
    006 1 001 1
    002 2 001 2
    003 3 002 3
    004 4 003 4
    这是你期望的结果
    */-->你就是把ID2当成lev了,而且还绕了个大弯,我直接这样就可以得到你期望的结果:
    select *, lev=ID2 from # order by ID2,IDdrop table #,#tmp_table
      

  6.   

    --创造测试数据
    create table #(ID char(3), ID2 int, parent char(3))
    insert # select '001', 1, '000'
    insert # select '002', 2, '001'
    insert # select '003', 3, '002'
    insert # select '004', 4, '003'
    insert # select '005', 1, '001'
    insert # select '006', 1, '001'select *,[lev]=cast(''as int) into #tmp_table from # where 1<>1declare @i int 
    set @i=1 
    --insert #tmp_table select ID,ID2,parent,@i from # where ID2=1--输入查询的参数 
    insert #tmp_table select ID,ID2,parent,@i from # a where ID2=1 and parent = (select min(parent) from # where ID2=a.ID2)while @@rowcount> 0 
    begin 
    set @i=@i+1 
    --insert #tmp_table select a.ID,a.ID2,a.parent,@i from # a join #tmp_table b on a.parent=b.ID and b.lev=@i-1 where not exists (select 1 from #tmp_table where ID = a.ID)
    insert #tmp_table select a.ID,a.ID2,a.parent,@i from # a join #tmp_table b on a.parent=b.ID and b.lev=@i-1
    end 
    --测试 
    select * from #tmp_table/*
    上面的数据得到的,应该才是你期望的结果:
    001 1 000 1
    002 2 001 2
    005 1 001 2
    006 1 001 2
    003 3 002 3
    004 4 003 4
    */-->产生重复的原因,就是你企图将不同LEVEL的放在同一个LEVELdrop table #,#tmp_table
      

  7.   


    select   *,[lev]=cast(''as   int)   into   #tmp_table   from   #   where   1 <> 1   declare   @i   int   
    set   @i=1   
    insert   #tmp_table   select   ID,ID2,parent,@i   from   #   where   ID2=1--输入查询的参数   while   @@rowcount> 0   
    begin   
            set   @i=@i+1   
            insert   #tmp_table   select   a.ID,a.ID2,a.parent,@i   from   #   a   join   #tmp_table   b   on   a.parent=b.ID   and   b.lev=@i-1 and a.ID2 >= @i
    end   
      

  8.   

    谢谢大家昨夜小楼
    -->你就是把ID2当成lev了,而且还绕了个大弯,我直接这样就可以得到你期望的结果:这个话不对,只是这里刚好有个ID2罢了, 这是我为了完成一个功能而做的简化测试,表结构只保留了我觉得实现我需要功能而必须的特征还有个问题, 还是造的表和测试数据,怎么根据一个记录的ID向上找出所有的祖先呢,比如
    drop   table   #    
    --创造测试数据   
    create   table   #(ID   char(3),               ID2   int,             parent   char(3))   
    insert   #   select   '001',                               1,                           '000'   
    insert   #   select   '002',                               2,                           '001'   
    insert   #   select   '003',                               3,                           '002'  
    insert   #   select   '004',                               4,                           '002'  
    insert   #   select   '005',                               4,                           '001'   
    insert   #   select   '006',                               1,                           '000'   
    根据
    '004', 4, '003' 的ID或parent找到
     
    '004',4,'003'
    '003',3,'002' 
    '002',2,'001'
    '001',1,'000'而不是得到
    '004',4,'003'
    '003',3,'002' 
    '005',4,'001'  没有这个
    '002',2,'001'
    '001',1,'000'
      

  9.   

    /*
    这个话不对,只是这里刚好有个ID2罢了, 这是我为了完成一个功能而做的简化测试,表结构只保留了我觉得实现我需要功能而必须的特征
    还有个问题, 还是造的表和测试数据,怎么根据一个记录的ID向上找出所有的祖先呢,比如
    */--创造测试数据 
    if object_id('tempdb.dbo.#') is not null drop table # 
    create table #(ID char(3), ID2 int, parent char(3)) 
    insert # select '001', 1, '000' 
    insert # select '002', 2, '001' 
    insert # select '003', 3, '002' 
    insert # select '004', 4, '003' -- 002 -> 003
    insert # select '005', 4, '001' 
    insert # select '006', 1, '000' /*
    根据
    '004', 4, '003' 的ID或parent
    找到
    '004',4,'003'
    '003',3,'002' 
    '002',2,'001'
    '001',1,'000'
    */-->这样当然得根据 ID 来取,Parent=003 或 ID2=4 的可能不仅仅是 004--> 2000方法
    if object_id('tempdb.dbo.#T') is not null drop table #T
    declare @Level int
    set @Level = 0
    select *, @Level as Level into #T from # where ID = '004'
    while @@rowcount > 0
    begin
    set @Level = @Level + 1
    insert #T select a.*, @Level from # a join #T b on a.ID = b.Parent where b.Level = @Level - 1
    end
    select ID,ID2,parent from #T order by Level--> 2005方法
    ;
    with Parent (ID, ID2, Parent) as
    (
    select * from # where ID = '004'
    union all
    select a.* from # a join Parent b on a.ID = b.Parent
    )
    select * from Parent
      

  10.   

    这个话不对,只是这里刚好有个ID2罢了,   这是我为了完成一个功能而做的简化测试
    ----------------------------------
    先不管它对不对首先肯定这一点:以ID2作为参数定位顶层的记录,按照你之前的写法,即使去除了重复,相同ID2记录的Level肯定是相同的。那么,不管你的ID2是什么类型,都可以通过简单的变换手段变成你要的Level。
      

  11.   

    上面:
    “以ID2作为参数定位顶层的记录,按照你之前的写法,即使去除了重复,相同ID2记录的Level肯定是相同的。”
    是不对的,相同ID2记录的Level不一定相同。所以
    “你就是把ID2当成lev了,而且还绕了个大弯,我直接这样就可以得到你期望的结果”
    也是不对的。