超级难题:如何取出下级所有部门代码(200分)

  • 主题发起人 主题发起人 wyj1974
  • 开始时间 开始时间
W

wyj1974

Unregistered / Unconfirmed
GUEST, unregistred user!
表结构:
部门ID、部门名称、上级部门ID

部门之间的层次关系不确定,一般可能是3级,但也可能是5、6级。

现在希望给出一个部门ID,能够找出其下级所有的部门ID

有没有好的办法解决这个问题,感谢!!!
 
一级一级往下查询就可以了
 
按这结构可以考虑部门Id和上级部门ID全部使用字符串,其中部门Id=上级部门ID+编号如:
部门ID 上级部门ID
0101 01
0102 01
0101001 0101
0101002 0101
0102001 0102
0102002 0102
0102003 0102
0102004 0102

这样不管实际有多少级,要找'0101002'下面所有子Id的话一句搞定:
select * from table1 where 部门Id like "0101002%"
 
JonnyZheng说的没错啊。递归的话代码比较容易写。但是SQL需要执行多次。
我的做法是先从数据库取出1级部门,然后每个部门取出其下的下一级,递归。对于宗部门数量不大的情况下,还是很快的。所有数据取出后放在内存中的树行数据结构。这样,接下来取部门所有下级部门操作,就不用访问数据库了,这样就更快。
你的问题还有修改表结构解决的方法。
以一个长的字符串存储部门ID,每4(或者更多更少,看每级部门有多少个而定)个字符作为一级进行编码。
如:
一级部门A编号0001,其下二级部门B编号00010001,C编号00010002
以此类推。对于层次有限的还是能够处理的。SQL就一次就行了。这种方案的问题是这个编号的维护比较麻烦。有得必有失。
 
Oracle中树结构查询方法
* T_TREE 表

结构:
ID NUMBER
PARENT_ID NUMBER
NAME VARCHAR2(32)

数据:
2 1 AAA
3 1 BBB
4 2 CCC
5 2 DDD
6 4 EEE
8 7 FFF

操作:
* 向上查询父:
SELECT * FROM T_TREE
START WITH ID = '6'
CONNECT BY ID = PRIOR PARENT_ID;

* 向下查询所有子:
SELECT * FROM T_TREE
START WITH ID = '4'
CONNECT BY PARENT_ID = PRIOR ID;

注意:查询操作的关键是表中树结构loop关系明确;
解决了一大部分树的递归、遍历等问题,不过仅限于Oracle数据库。
 
树的遍历+递归
 
建立函数
Create Function FindDepID (
@ID int,
@PID int
) Returns int
AS
Begin
Declare @tid int
Set @tid = @ID
Select @tid = 上级部门ID From 部门表 Where 部门ID = @tid
if @tid = @PID
Return 1
else
Return 0
End

然后用,测试看看。 没有测试
Select 部门ID From 表 where dbo.FindDepID(部门ID,你要查找的部门ID) = 1
 
function findchildID(ParentID: Integer,Var IDstr : string):string;
var
adoquery: TADOQuery;
tempstr : string;
begin
adoquery := TADOQuery.Create(nil);
try
adoquery.sql.txt:='select 部门ID,部门名称,上级部门ID from 部门 where 上级部门ID = ID order by 上级部门ID';
...................
while not adoquery.Eof do
begin
tempstr := adoquery.fieldbyname('部门ID').AsString;
IDstr:=IDstr+','+tempstr;
findchildID(strtoint(tempstr),IdStr);
adoquery.Next;
end;
adoquery.Close;
finally
adoquery.Free;
end;
Result:=IDstr;
end;

这个很清楚了把
 
创意、自由、灵活,超强的报表功能,
独特的双数据源连接,全功能的表格组件!

http://www.anylib.com
 
http://bbs.2ccc.com/topic.asp?topicid=183543
 
同意gxw,不建议一级级往下查的方法。
 
我来搞定给你吧! 哈哈。
建立函数
Create Function FindDepID (
@ID int,
@PID int
) Returns int
AS
Begin
Declare @tid int, @count int, @tmp int
Select @tid = @ID, @tmp = 1, @count = count(1) from 部门表
while @tmp <= @count --这个条件你可以自己优化一下
begin
set @tmp = @tmp + 1
Select @tid = 上级部门ID From 部门表 Where 部门ID = @tid
if @tid = @PID Return 1
end
Return 0
End

然后用, 测试通过
Select 部门ID From 部门表 where dbo.FindDepID(部门ID,你要查找的部门ID) = 1
 
select * from table1 where left(ID,2)='01' and length(ID)>2
 
部门表结构
CREATE TABLE [Dept] (
代码:
 [varchar] (10) NULL ,
  [Name] [varchar] (50) NULL ,
  [ParentCode] [varchar] (10) NULL ,
  [Level] [tinyint] NULL ,
)  ON [PRIMARY] 
取下级部门函数
CREATE FUNCTION dbo.FP_GetNextDept(@Code varchar(10))
RETURNS varchar(4096) WITH ENCRYPTION AS
BEGIN
  DECLARE @name varchar(4096),@Next varchar(10),@tmp varchar(4096)
  SELECT @name='',@Next=''
  DECLARE RecNo CURSOR SCROLL FOR SELECT ISNULL(Code,'') FROM Dept WHERE ParentCode=@Code
  OPEN RecNo
  FETCH FIRST FROM RecNo INTO @Next
  WHILE @@FETCH_STATUS=0
  BEGIN
    SELECT @tmp=dbo.FP_GetNextDept(@Next)
    IF @tmp<>'' SELECT @tmp=@tmp+','
    SELECT @name=@name+''''+@Next+''','+LTRIM(RTRIM(@tmp))
    FETCH NEXT FROM RecNo INTO @Next
  END
  IF @name<>'' SELECT @name=SUBSTRING(@name,1,LEN(@name)-1)
  RETURN @name
END
GO
 
你这个家伙是不是得了答案就不给分了?
 
嗯,现在大富翁上有许多不遵守游戏规则的...
我就回答了很多问题然后楼主得了答案后就蒸发了,建议楼上的兄弟也别太认证了,大热天的,容易上火。
 
人家拿着分可是很有用的,起码可以买...
 
那是的。以后我也只来看看了,不能发表意见了
 
加一个指针字段
 

Similar threads

D
回复
0
查看
825
DelphiTeacher的专栏
D
D
回复
0
查看
769
DelphiTeacher的专栏
D
D
回复
0
查看
719
DelphiTeacher的专栏
D
后退
顶部