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语句,使得不出现重复数据?
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语句,使得不出现重复数据?
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
但是这不是最好的办法, 如果能够在循环里就控制好根本不插入多余的行不是更好, 怎么做呢? 有人知道吗?
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)
修改下看看
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
* 菜菜鸟
* 等 级:
的方法是正确的。但你需求的结果可能不对。
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
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
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
-->你就是把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'
这个话不对,只是这里刚好有个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
----------------------------------
先不管它对不对首先肯定这一点:以ID2作为参数定位顶层的记录,按照你之前的写法,即使去除了重复,相同ID2记录的Level肯定是相同的。那么,不管你的ID2是什么类型,都可以通过简单的变换手段变成你要的Level。
“以ID2作为参数定位顶层的记录,按照你之前的写法,即使去除了重复,相同ID2记录的Level肯定是相同的。”
是不对的,相同ID2记录的Level不一定相同。所以
“你就是把ID2当成lev了,而且还绕了个大弯,我直接这样就可以得到你期望的结果”
也是不对的。