首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

权限树取树,设计到一个限构图,求高手解答

2012-12-18 
权限树取树,设计到一个限制表,求高手解答本帖最后由 xxyping 于 2012-12-07 09:11:19 编辑idpid表10010020

权限树取树,设计到一个限制表,求高手解答
本帖最后由 xxyping 于 2012-12-07 09:11:19 编辑 idpid表1
0
010
020
030
010101
010201
020102
030103
030203
0101010101
0201010201
01010101 010101
0302010302
0302020302

iddid表2
101010101
103
10201

表1是一个树表
表2是查找限制表
想要找到所有树下面的最后一层节点
例如:id-0,这样我找到数据应该是01010101\030201\030202\020101
也就是说找的数据是根据表2来限制的,如果表2中有匹配的id为0的,则找到它下面所有的最后一层节点,否则就按照表2中的匹配关系,找到它的子节点下有设置关系的所有最后一层节点
假如id-01,则只能找到01010101;
03的话可以找到030201\030202

求高手给个取树方案,谢谢


[最优解释]


--那你试下这个,bom表太大的话,会比较慢,可以分2次展bom
declare @t1 table(id varchar(10),pid varchar(10))
insert into @t1 values('01','0')
insert into @t1 values('02','0')
insert into @t1 values('03','0')
insert into @t1 values('0101','01')
insert into @t1 values('0102','01')
insert into @t1 values('0201','02')
insert into @t1 values('0301','03')
insert into @t1 values('0302','03')
insert into @t1 values('010101','0101')
insert into @t1 values('020101','0201')
insert into @t1 values('01010101','010101')
insert into @t1 values('030201','0302')
insert into @t1 values('030202','0302')


declare @t2 table(id int, did varchar(10))
insert into @t2 values(1,'01010101')
insert into @t2 values(2,'03')
insert into @t2 values(3,'0201')



declare @id varchar(10) 
set @id='0302'

;with cte_bom
as
(
select id,pid ,
rights= case when exists(select 1 from @t2 where did=A.pid )
             then 1 else 0 end,
flag = case when pid=@id or id=@id then 1 else 0 end
 from @t1 as A where not exists(select 1 from @t1 where id=A.pid)
union all
select A.id,A.pid, 
case when cte_bom.rights =1 then 1 else
                        case when exists(select 1 from @t2 where did=A.pid )
                             then 1 else 0 end
                        end,
flag = case when flag=1 then 1 else
         case when A.id=@id then 1 else 0 end
       end
from cte_bom,@t1 as A
where cte_bom.id = A.pid
)

select id,pid
from cte_bom as A
where not exists(select 1 from @t1 where pid=A.id)
and (rights=1 or exists(select 1 from @t2 where did=A.id ) )
and flag=1


------其他解决方案--------------------



----------------------------
-- Author  :TravyLee(物是人非事事休,欲语泪先流!)
-- Date    :2012-12-07 09:14:02
-- Version:

--      Microsoft SQL Server 2012 - 11.0.2100.60 (Intel X86) 

--Feb 10 2012 19:13:17 

--Copyright (c) Microsoft Corporation

--Enterprise Edition: Core-based Licensing on Windows NT 6.1 <X86> (Build 7601: Service Pack 1)

--
----------------------------
--> 测试数据:[a]
if object_id('[a]') is not null 
drop table [a]
go 
create table [a]
(
[id] varchar(8),
[pid] varchar(6)
)
insert [a]
select '0',null union all
select '01','0' union all
select '02','0' union all
select '03','0' union all
select '0101','01' union all
select '0102','01' union all
select '0201','02' union all
select '0301','03' union all
select '0302','03' union all
select '010101','0101' union all
select '020101','0201' union all
select '01010101','010101' union all
select '030201','0302' union all
select '030202','0302'
--> 测试数据:[b]
if object_id('[b]') is not null 
drop table [b]
go 
create table [b]
(
[id] int,
[did] varchar(8)
)
insert [b]
select 1,'01010101' union all
select 1,'03' union all
select 1,'0201'
go


DECLARE @id varchar(20)
SET @id = '0'
;WITH
T AS(
 -- 定位点成员
 select *,levels=0 FROM [a]
 WHERE id = @id
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*,B.levels+1
 FROM [a] A, T B
 WHERE A.[pid] = B.id
)
select
* from t where not exists(select 1 from t a where t.id=a.pid)


/*
idpidlevels
0301032
03020103023
03020203023
02010102013
0102012
010101010101014
*/



--我这个是把指定节点下的所有最底层的子节点都找出来了  但看不明白你的第二张表   不知道怎么用    你也没介绍一下   只知道说限制  那怎么个限制  举个例子
[其他解释]
既然是id、pid机制了,类型应该是普通的整数就行了,为什么还是这种多级的字符串?
多级的字符串本身就蕴含了pid的信息了

第二个表没看明白
[其他解释]
@sz_haitao 
第二个表是一个限制表,类似一个树形权限的限制表,我可以设置这个树上的任意一个节点到这个表中,起到一个控制作用,例如表2中的id类似一个人员ID,我可以为这个人员设置一个权限,权限的高低是用树中的节点控制的,第一层可以看到下面层的所有数据,也就是说上层可以看到下层的数据,下层看不到上层的。。。。至于ID,也可以用整数的,呵呵
[其他解释]
上面已经说过限制了,可能说的不清楚,再说一下,就是说第二个表是一个控制表,类似权限控制,可以设置他能看到的层次,设置的上层可以看到下层
[其他解释]
你的表述似乎有问题,取 0 或者 03 的时候,根据第二个表,你的0301呢?也是最底层节点。
[其他解释]

--试试看这个是不是要的结果
declare @t1 table(id varchar(10),pid varchar(10))


insert into @t1 values('01','0')
insert into @t1 values('02','0')
insert into @t1 values('03','0')
insert into @t1 values('0101','01')
insert into @t1 values('0102','01')
insert into @t1 values('0201','02')
insert into @t1 values('0301','03')
insert into @t1 values('0302','03')
insert into @t1 values('010101','0101')
insert into @t1 values('020101','0201')
insert into @t1 values('01010101','010101')
insert into @t1 values('030201','0302')
insert into @t1 values('030202','0302')

declare @t2 table(id int, did varchar(10))
insert into @t2 values(1,'01010101')
insert into @t2 values(2,'03')
insert into @t2 values(3,'0201')


declare @id varchar(10) 
set @id='0' --要查看的父节点

;with cte_bom
as
(
select id,pid ,flag= case when exists(select 1 from @t2 where did=A.pid )
                     then 1 else 0 end
 from @t1 as A where pid=@id
union all
select A.id,A.pid, case when cte_bom.flag =1 then 1 else
                        case when exists(select 1 from @t2 where did=A.pid )
                             then 1 else 0 end
                        end
from cte_bom,@t1 as A
where cte_bom.id = A.pid
)

select id,pid
from cte_bom as A
where not exists(select 1 from @t1 where pid=A.id)
and (flag=1 or exists(select 1 from @t2 where did=A.id ) )

/*
id       pid
-------------------------
030103
0302010302
0302020302
0201010201
01010101010101
*/


[其他解释]
加入表2中现在只有一条数据,然后它设置的是01010101,然后他只能看到01010101下面的所有数据,如果设置的是01,他能看到的数据就是整个01下面的数据,目前我的数据是根据最后一层的节点来找的,所以需要得出最后一层节点的ID

[其他解释]
谢谢@playwarcraft,这个应该是可以满足我的需求的,但是现在有个问题是,我树上可以看到030201,这个数据在表2中是没有的,用这个编号中是找不到数据的,但是他的父亲节点在,所以,我想要的结果是如果这个节点的父亲在表中,要能查找到这个节点,若果这个节点不是最后一层节点,也要能查找到它的最后一层子节点

不知道这样说可明白,呵呵
[其他解释]
@playwarcraft   好的,我先试试看,谢谢先

热点排行