比如表结构数据如下:
Table:Tree
ID Name ParentId
1 一级 0
2 二级 1
3 三级 2
4 四级 3
SQL SERVER 2005查询方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //上查
with tmpTree
as
(
select * from Tree where Id=2
union all
select p.* from tmpTree inner join Tree p on p.Id=tmpTree.ParentId
)
select * from tmpTree
//下查
with tmpTree
as
(
select * from Tree where Id=2
union all
select s.* from tmpTree inner join Tree s on s.ParentId=tmpTree.Id
)
select * from tmpTree
|
SQL SERVER 2008及以后版本,还可用如下方法:
增加一列TID,类型设为:hierarchyid(这个是CLR类型,表示层级),且取消ParentId字段,变成如下:(表名为:Tree2)
TId Id Name
0x 1 一级 0x58 2 二级 0x5B40 3 三级 0x5B5E 4 四级
查询方法:
1 2 3 4 5 6 7 8 9 | SELECT *,TId.GetLevel() as [ level ] FROM Tree2 --获取所有层级
DECLARE @ParentTree hierarchyid
SELECT @ParentTree=TId FROM Tree2 WHERE Id=2
SELECT *,TId.GetLevel() AS [ level ] FROM Tree2 WHERE TId.IsDescendantOf(@ParentTree)=1 --获取指定的节点所有下级
DECLARE @ChildTree hierarchyid
SELECT @ChildTree=TId FROM Tree2 WHERE Id=3
SELECT *,TId.GetLevel() AS [ level ] FROM Tree2 WHERE @ChildTree.IsDescendantOf(TId)=1 --获取指定的节点所有上级
|
可参见相关文章:http://blog.csdn.net/szstephenzhou/article/details/8277667
ORACLE中的查询方法:
1 2 3 4 5 6 7 8 9 | SELECT *
FROM Tree
START WITH Id=2
CONNECT BY PRIOR ID=ParentId --下查
SELECT *
FROM Tree
START WITH Id=2
CONNECT BY ID= PRIOR ParentId --上查
|
可参见相关文章:http://blog.csdn.net/super_marioli/article/details/6253639
MYSQL 中的查询方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | //定义一个依据ID查询所有父ID为这个指定的ID的字符串列表,以逗号分隔
CREATE DEFINER=`root`@`localhost` FUNCTION `getChildLst`(rootId int ,direction int ) RETURNS varchar (1000) CHARSET utf8
BEGIN
DECLARE sTemp VARCHAR (5000);
DECLARE sTempChd VARCHAR (1000);
SET sTemp = '$' ;
IF direction=1 THEN
SET sTempChd = cast (rootId as CHAR );
ELSEIF direction=2 THEN
SELECT cast (ParentId as CHAR ) into sTempChd FROM Tree WHERE Id=rootId;
END IF;
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',' ,sTempChd);
SELECT group_concat(id) INTO sTempChd FROM Tree where (direction=1 and FIND_IN_SET(ParentId,sTempChd)>0)
or (direction=2 and FIND_IN_SET(Id,sTempChd)>0);
END WHILE;
RETURN sTemp;
END
//查询方法:
select * from tree where find_in_set(id,getChildLst(1,1)); --下查
select * from tree where find_in_set(id,getChildLst(1,2)); --上查
|
补充说明:上面这个方法在下查是没有问题,但在上查时会出现问题(详见博问:http://q.cnblogs.com/q/76375/),原因在于我的逻辑写错了,存在死循环,现已修正,新的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | CREATE DEFINER=`root`@`localhost` FUNCTION `getChildLst`(rootId int ,direction int ) RETURNS varchar (1000) CHARSET utf8
BEGIN
DECLARE sTemp VARCHAR (5000);
DECLARE sTempChd VARCHAR (1000);
SET sTemp = '$' ;
SET sTempChd = cast (rootId as CHAR );
IF direction=1 THEN
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',' ,sTempChd);
SELECT group_concat(id) INTO sTempChd FROM Tree where FIND_IN_SET(ParentId,sTempChd)>0;
END WHILE;
ELSEIF direction=2 THEN
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',' ,sTempChd);
SELECT group_concat(ParentId) INTO sTempChd FROM Tree where FIND_IN_SET(Id,sTempChd)>0;
END WHILE;
END IF;
RETURN sTemp;
END
|
这样递归查询就很方便了。
可参见相关文章:http://blog.csdn.net/jackiehome/article/details/6803978
说明:以上知识点均来源于网上,我这里只是做一个合计总结。
|