请教:已知一节点可以有最多2个父结点, 求该结点的父结点,及父结点的父结点... ...

Jeremiah 2010-06-28 07:38:27
现在有表结构如下:
id parentID1 parentID2
1 2 3
2 4 NULL
3 4 5
4 5 NULL
5 9
... ... ....
... ... ....
9 NULL NULL
... ... ....
... ... ....
假如想要知道id=1的父结点, 及其父结点的父结点,那么结果就是:
2, 3, 4, 5, 9

请教在function(可以使用多个function)中如何实现这样的功能.
...全文
184 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jeremiah 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 xys_777 的回复:]

SQL code

if OBJECT_ID('tb') is not null drop table tb;
go
create table tb (
id int,
parentID1 int,
parentID2 int );
go
insert into tb
select 1, 2, 3 union all
select 2,4, NULL union……
[/Quote]
thanks,
明白了, 把parentID1与ParentID2 Union成为一列, 就可以进行递归了...

[Quote=引用 13 楼 obuntu 的回复:]
你可以研究下CTE,对这种递归的最合适了。
[/Quote]

谢谢~
obuntu 2010-06-28
  • 打赏
  • 举报
回复
你可以研究下CTE,对这种递归的最合适了。
永生天地 2010-06-28
  • 打赏
  • 举报
回复

if OBJECT_ID('tb') is not null drop table tb;
go
create table tb (
id int,
parentID1 int,
parentID2 int );
go
insert into tb
select 1, 2, 3 union all
select 2,4, NULL union all
select 3 ,4,5 union all
select 4 ,5, NULL union all
select 5 ,9,null
go

--查所有父结点
if object_id('f_getP') is not null drop function f_getP
go
create function f_getP(@id int)
returns @re table(id int,level int)
as
begin
declare @l int
set @l=0
insert @re select @id,@l
while @@rowcount>0
begin
set @l=@l+1
insert @re select a.parentid,@l from
(select id,parentID1 parentid from tb union select id,parentID2 from tb)a
,@re b
where a.id=b.id and b.level=@l-1 and a.parentid is not null
end
update @re set level=@l-level
return
end
go

SELECT distinct id FROM dbo.f_getP(1) where id<>1
go

/*

(5 行受影响)
id
-----------
2
3
4
5
9

(5 行受影响)

*/
永生天地 2010-06-28
  • 打赏
  • 举报
回复
可以先union
select id ,parentID1 from tb union
select id ,parentID2 from tb

在使用这些函数
http://blog.csdn.net/xys_777/archive/2010/06/15/5672481.aspx
Jeremiah 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 nightmaple 的回复:]

#7返回的表table

select parentID1 from table
union select parentID2 from table

即为所要的父类ID
[/Quote]

不太好意思, 没看明白~
Jeremiah 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 nightmaple 的回复:]

#7返回的表table

select parentID1 from table
union select parentID2 from table

即为所要的父类ID
[/Quote]

谢了~ 明天上班的时候,在开发环境中试一下,然后结贴~
nightmaple 2010-06-28
  • 打赏
  • 举报
回复
#7返回的表table

select parentID1 from table
union select parentID2 from table

即为所要的父类ID
nightmaple 2010-06-28
  • 打赏
  • 举报
回复
create table tbl
(
id int,
parentID1 int,
parentID2 int
)
go

insert into tbl
select 1, 2, 3 union all select
2,4, NULL union all select
3 ,4,5 union all select
4 ,5, NULL union all select
5 ,9,null
go

IF OBJECT_ID('GetTreeNode','tf') IS NOT NULL
DROP FUNCTION GetTreeNode
GO

CREATE FUNCTION GetTreeNode(@id int)
RETURNS @t2 table(id INT,id2 int,id3 int)
AS
BEGIN
DECLARE @t1 TABLE(id int)
DECLARE @t3 TABLE(id int)
INSERT INTO @t1 SELECT @id
INSERT INTO @t3 SELECT @id

WHILE EXISTS(SELECT 1 FROM tbl WHERE id in (select id from @t1))
BEGIN
INSERT INTO @t2 SELECT id,parentID1,parentID2 FROM tbl WHERE id in (select id from @t1)

IF EXISTS(SELECT 1 FROM tbl WHERE (id IN (SELECT id2 FROM @t2)) or (id IN (SELECT id3 FROM @t2)))
BEGIN
DECLARE @temp TABLE(id int)
INSERT INTO @temp SELECT id FROM tbl WHERE (id not in (select id from @t3)) and (id IN (SELECT id2 FROM @t2) or id IN (SELECT id3 FROM @t2))
DELETE FROM @t1
INSERT INTO @t1 SELECT * FROM @temp
INSERT INTO @t3 SELECT * FROM @temp
DELETE FROM @temp
END
ELSE
BEGIN
RETURN
END
END
RETURN
END
GO

SELECT * FROM dbo.GetTreeNode(4)
go
Jeremiah 2010-06-28
  • 打赏
  • 举报
回复
我整理了一下思路,用人伪代码, 请各位看一看是否正确.
set @parentID1 = select parentID1 from table where id = @ID
set @parentID2 = select parentID2 from table where id = @ID
declare @tbl table(....)
function GetParentNodes(@parentID1, @parentID2, @tbl)
{
set @parentID11 = select parentID1 from table where id = @parentID1
set @parentID22 = select parentID2 from table where id = @parentID1
@tbl.Add(@parentID11)
@tbl.Add(@parentID22)
GetParentNodes(@parentID11,@parentID22,@tbl)

set @parentID11 = null
set @parentID22 = null

set @parentID11 = select parentID1 from table where id = @parentID2
set @parentID22 = select parentID2 from table where id = @parentID2
@tbl.Add(@parentID11)
@tbl.Add(@parentID22)
GetParentNodes(@parentID11,@parentID22,@tbl)
}
@tbl的distinct 即为所求
Jeremiah 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 thinclient 的回复:]

明显的地龟
[/Quote]

应该需要递归, 不过他的分支有些多,
假如结点1有2个父结点的话, 每一个父结点又可能会有2个父结点... ... 这样下去有些多.
我感觉像是在遍历二叉树一样~ 一时半回,没思路~

求解~ 谢谢~
Jeremiah 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 nightmaple 的回复:]

parentID2是干什么的?parentID1,parentID2两个都要查?
[/Quote]
是的, 是2个父结点的都要查找.
thinclient 2010-06-28
  • 打赏
  • 举报
回复
对,两个父
nightmaple 2010-06-28
  • 打赏
  • 举报
回复
parentID2是干什么的?parentID1,parentID2两个都要查?
thinclient 2010-06-28
  • 打赏
  • 举报
回复
明显的地龟

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧