难!难!难!在多级父子表中,如何用一条SQL语句根据子记录(id)得到最上层父记录(id)(附数据结构及数据)?

时间:2021-05-16 21:53:43
以下是数据结构及我自己随便构造出来的数据,一般只有两级,目前我列出三级,但可能再扩展多级:
menuno   menuname   parent_menuno  levelno  ......
  1       系统管理                    0
  2       用户管理        1           1  
  3       角色管理        1           1
  4       组织机构        1           1
  5       菜单管理        1           1
  6       功能管理        1           1
  7       权限管理    1           1
  8       功能权限        7           2
  9       数据权限        7           2
  ......  
如何用一条SQL语句根据子记录得到最上最上层父记录(id),有可能吗?
比如有可能得到"menuno"是"9"的记录,如何得到其最次层的父记录"menuno"是"1"?

9 个解决方案

#1


写个函数,类似这个:
------------------------------------------------------------------------------------------------------------------------------------
--生成测试数据
create table BOM(ID VARCHAR(10),PID VARCHAR(10))
insert into BOM select 'a',NULL
insert into BOM select 'b','a'
insert into BOM select 'c','a'
insert into BOM select 'd','b'
insert into BOM select 'e','b'
insert into BOM select 'f','c'
insert into BOM select 'g','c'
go

--创建用户定义函数
create function f_getRoot(@ID VARCHAR(10))
returns VARCHAR(10)
as
begin
    declare @PID VARCHAR(10)
    select @PID=PID from BOM where ID=@ID and PID is not null
    while @@rowcount<>0
    begin
        SET @ID=@PID
        select @PID=PID from BOM where ID=@ID and PID is not null
    end
    return @ID
end
go

--执行查询
select ID,dbo.f_getRoot(ID) PID from BOM group by ID
go

--输出结果
/*
ID         PID        
---------- ---------- 
a          a
b          a
c          a
d          a
e          a
f          a
g          a
*/

--删除测试数据
drop function f_getRoot
drop table BOM

#2


一条语句,oracle可以,MS SQL SERVER不行

#3


如果通过"menuno"是"9"的记录,如何得到其所有次层的父记录"menuno"是"1"?

通过:
menuno   menuname   parent_menuno  levelno
 9       数据权限        7           2

得到:
menuno   menuname   parent_menuno  levelno
  1       系统管理                    0
  2       用户管理        1           1  
  3       角色管理        1           1
  4       组织机构        1           1
  5       菜单管理        1           1
  6       功能管理        1           1
  7       权限管理    1           1
  9       数据权限        7           2

#4


先谢谢 libin_ftsafe(子陌红尘) ,不用函数用SQL语句能实现吗?

请问 pmz() ,oracel怎么实现?

#5


写一个存储过程,思想是这样的,先由menuno得到level_no,即得出它是几级,然后用级别做为循环的次数变量,如下所示
declare @levelno varchar(10)
declare @yourlevel varchar(10) ----这是你想得到第几层
declare @parentno varchar(10) output
declare @parentno1 varchar(10)
select @yourlevel = "0"
select @levelno=level_no,@parentno1=parent_menuno from 表名 where menuno='9'
while @levelno>@yourlevel+1
begin
   select @parentno=parent_menuno from 表名 where menuno=@parentno1
   select @parentno1=@parentno
   select @levelno=@levelno-1
end
具体的自己写好了

#6


大哥,我现在就是不想用存储过程、函数之类的,如果用我就自己写了,不用在这里问了!!!!即使用,也不能像你这样写....

#7


一句好难,期待有答案,学习

#8


没有了吗?

#9


比如有可能得到"menuno"是"9"的记录,如何得到其最次层的父记录"menuno"是"1"?
我是没看懂这句话,道行不深啊^_^

#1


写个函数,类似这个:
------------------------------------------------------------------------------------------------------------------------------------
--生成测试数据
create table BOM(ID VARCHAR(10),PID VARCHAR(10))
insert into BOM select 'a',NULL
insert into BOM select 'b','a'
insert into BOM select 'c','a'
insert into BOM select 'd','b'
insert into BOM select 'e','b'
insert into BOM select 'f','c'
insert into BOM select 'g','c'
go

--创建用户定义函数
create function f_getRoot(@ID VARCHAR(10))
returns VARCHAR(10)
as
begin
    declare @PID VARCHAR(10)
    select @PID=PID from BOM where ID=@ID and PID is not null
    while @@rowcount<>0
    begin
        SET @ID=@PID
        select @PID=PID from BOM where ID=@ID and PID is not null
    end
    return @ID
end
go

--执行查询
select ID,dbo.f_getRoot(ID) PID from BOM group by ID
go

--输出结果
/*
ID         PID        
---------- ---------- 
a          a
b          a
c          a
d          a
e          a
f          a
g          a
*/

--删除测试数据
drop function f_getRoot
drop table BOM

#2


一条语句,oracle可以,MS SQL SERVER不行

#3


如果通过"menuno"是"9"的记录,如何得到其所有次层的父记录"menuno"是"1"?

通过:
menuno   menuname   parent_menuno  levelno
 9       数据权限        7           2

得到:
menuno   menuname   parent_menuno  levelno
  1       系统管理                    0
  2       用户管理        1           1  
  3       角色管理        1           1
  4       组织机构        1           1
  5       菜单管理        1           1
  6       功能管理        1           1
  7       权限管理    1           1
  9       数据权限        7           2

#4


先谢谢 libin_ftsafe(子陌红尘) ,不用函数用SQL语句能实现吗?

请问 pmz() ,oracel怎么实现?

#5


写一个存储过程,思想是这样的,先由menuno得到level_no,即得出它是几级,然后用级别做为循环的次数变量,如下所示
declare @levelno varchar(10)
declare @yourlevel varchar(10) ----这是你想得到第几层
declare @parentno varchar(10) output
declare @parentno1 varchar(10)
select @yourlevel = "0"
select @levelno=level_no,@parentno1=parent_menuno from 表名 where menuno='9'
while @levelno>@yourlevel+1
begin
   select @parentno=parent_menuno from 表名 where menuno=@parentno1
   select @parentno1=@parentno
   select @levelno=@levelno-1
end
具体的自己写好了

#6


大哥,我现在就是不想用存储过程、函数之类的,如果用我就自己写了,不用在这里问了!!!!即使用,也不能像你这样写....

#7


一句好难,期待有答案,学习

#8


没有了吗?

#9


比如有可能得到"menuno"是"9"的记录,如何得到其最次层的父记录"menuno"是"1"?
我是没看懂这句话,道行不深啊^_^