我是甲骨文新手...相对来说......
我正在尝试在我继承的Oracle表上使用CTE。它比我希望的要复杂一点,因为“顶层”没有明确定义。
create table testConnectBy ( parent number, child number );
insert into testConnectBy values ( 1, 1);
insert into testConnectBy values ( 1, 11);
insert into testConnectBy values ( 1, 12);
insert into testConnectBy values ( 2, 2);
insert into testConnectBy values ( 2, 13);
insert into testConnectBy values (11, 11);
insert into testConnectBy values (11, 20);
insert into testConnectBy values (11, 21);
insert into testConnectBy values (12, 12);
insert into testConnectBy values (12, 22);
insert into testConnectBy values (12, 23);
insert into testConnectBy values (12, 24);
insert into testConnectBy values (13, 13);
insert into testConnectBy values (13, 30);
insert into testConnectBy values (13, 31);
insert into testConnectBy values (30, 30);
insert into testConnectBy values (30, 40);
此查询获取所有必需的行但是有一些重复(这是问题的第一部分,我想,最好如何删除)。由于存在循环问题(父==孩子),我不得不包括nocycle。
select *
from testConnectBy
start with parent = '1'
connect by nocycle prior child = parent;
下一个问题是,我希望能够输入11例如,并找出所有的父母和孩子。我不知道哪些父母或孩子与11有关。只是我需要用11来找到它们。
此查询仅返回11的子项。有没有办法返回两个“方向”?
select *
from testConnectBy
start with parent = '11'
connect by nocycle prior child = parent;
提前致谢。
答案 0 :(得分:1)
关于第一个问题,请使用以下内容。它没有任何可以在PATH中检查的副本
SELECT
PARENT,
CHILD,
LEVEL,
CONNECT_BY_ISLEAF AS ISLEAF,
CONNECT_BY_ISCYCLE AS ISCYCLE,
CONNECT_BY_ROOT PARENT
|| SYS_CONNECT_BY_PATH ( CHILD,
' ~ ' )
AS PATH
FROM
TESTCONNECTBY
CONNECT BY
NOCYCLE PARENT = PRIOR CHILD
START WITH
PARENT = '1';
这将返回
1 1 1 0 1 1 ~ 1
1 11 2 0 1 1 ~ 1 ~ 11
11 20 3 1 0 1 ~ 1 ~ 11 ~ 20
11 21 3 1 0 1 ~ 1 ~ 11 ~ 21
1 12 2 0 1 1 ~ 1 ~ 12
12 22 3 1 0 1 ~ 1 ~ 12 ~ 22
12 23 3 1 0 1 ~ 1 ~ 12 ~ 23
12 24 3 1 0 1 ~ 1 ~ 12 ~ 24
1 11 1 0 1 1 ~ 11
11 20 2 1 0 1 ~ 11 ~ 20
11 21 2 1 0 1 ~ 11 ~ 21
1 12 1 0 1 1 ~ 12
12 22 2 1 0 1 ~ 12 ~ 22
12 23 2 1 0 1 ~ 12 ~ 23
12 24 2 1 0 1 ~ 12 ~ 24
如果你想避免PARENT = CHILDREN,那么
SELECT
PARENT,
CHILD,
LEVEL,
CONNECT_BY_ISLEAF AS ISLEAF,
CONNECT_BY_ISCYCLE AS ISCYCLE,
CONNECT_BY_ROOT PARENT
|| SYS_CONNECT_BY_PATH ( CHILD,
' ~ ' )
AS PATH
FROM
(SELECT * FROM TESTCONNECTBY WHERE PARENT <> CHILD)
CONNECT BY
NOCYCLE PARENT = PRIOR CHILD
START WITH
PARENT = '1';
结果
1 11 1 0 0 1 ~ 11
11 20 2 1 0 1 ~ 11 ~ 20
11 21 2 1 0 1 ~ 11 ~ 21
1 12 1 0 0 1 ~ 12
12 22 2 1 0 1 ~ 12 ~ 22
12 23 2 1 0 1 ~ 12 ~ 23
12 24 2 1 0 1 ~ 12 ~ 24
对于第二个问题,您可以使用以下代码段
SELECT
*
FROM
(SELECT
PARENT,
CHILD,
LEVEL,
CONNECT_BY_ISLEAF AS ISLEAF,
CONNECT_BY_ISCYCLE AS ISCYCLE,
CONNECT_BY_ROOT PARENT
|| SYS_CONNECT_BY_PATH ( CHILD,
' ~ ' )
AS PATH
FROM
TESTCONNECTBY
CONNECT BY
NOCYCLE PARENT = PRIOR CHILD
START WITH
PARENT = '1')
WHERE
PARENT = 11
OR CHILD = 11;
此查询返回
1 11 2 0 1 1 ~ 1 ~ 11
11 20 3 1 0 1 ~ 1 ~ 11 ~ 20
11 21 3 1 0 1 ~ 1 ~ 11 ~ 21
1 11 1 0 1 1 ~ 11
11 20 2 1 0 1 ~ 11 ~ 20
11 21 2 1 0 1 ~ 11 ~ 21
因为父母11有一个孩子11.如果你想排除自己的孩子,那么
SELECT
*
FROM
(SELECT
PARENT,
CHILD,
LEVEL,
CONNECT_BY_ISLEAF AS ISLEAF,
CONNECT_BY_ISCYCLE AS ISCYCLE,
CONNECT_BY_ROOT PARENT
|| SYS_CONNECT_BY_PATH ( CHILD,
' ~ ' )
AS PATH
FROM
(SELECT * FROM TESTCONNECTBY WHERE PARENT <> CHILD)
CONNECT BY
NOCYCLE PARENT = PRIOR CHILD
START WITH
PARENT = '1')
WHERE
PARENT = 11
OR CHILD = 11;
将返回
1 11 1 0 0 1 ~ 11
11 20 2 1 0 1 ~ 11 ~ 20
11 21 2 1 0 1 ~ 11 ~ 21