比如表结构数据如下:
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.youkuaiyun.com/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.youkuaiyun.com/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
|