Oracle SQL 启动 with/prior
Oracle SQL start with/prior
我已经成功地理解了按级别连接如何与下面的示例一起工作:
SELECT
level,
t.*
FROM
(
SELECT
'a' AS col1,
'b' AS col2
FROM
dual
UNION ALL
SELECT
'c',
'd'
FROM
dual
) t
CONNECT BY
level <= 3
但是,我很难理解 'start with' 和 'prior' 的概念以及它们在现实生活中的用例。有人可以使用提供的示例指导我吗?
如果你们有 parent/child 关系:
CREATE TABLE t ( parent, child ) AS
SELECT 'a', 'b' FROM dual UNION ALL
SELECT 'b', 'c' FROM dual UNION ALL
SELECT 'c', 'd' FROM dual UNION ALL
SELECT 'd', 'e' FROM dual;
并且你想获取从b
开始的家谱并获取所有后代,那么你可以:
SELECT level,
t.*
FROM t
START WITH parent = 'b'
CONNECT BY PRIOR child = parent
输出:
LEVEL | PARENT | CHILD
----: | :----- | :----
1 | b | c
2 | c | d
3 | d | e
第 1 级以 b
开头,然后第 2 级有 b
的 child c
然后第 3 级有 b
的 child 的 child (grandchild) d
并且它们都通过 PRIOR
child
是(当前)parent
的关系连接].
有关如何获得不同关系的更多示例,请参见 。
顺便说一句,您在问题中的示例有点令人困惑,因为它找到了深度为 3 的递归的所有路径。如果您使用 SYS_CONNECT_BY_PATH
显示它通过数据所采用的路径,那么您会得到一个更好的主意:
SELECT level,
t.*,
SYS_CONNECT_BY_PATH( '('||col1||','||col2||')', '->' ) AS path
FROM (
SELECT 'a' AS col1, 'b' AS col2 FROM dual UNION ALL
SELECT 'c', 'd' FROM dual
) t
CONNECT BY level <= 3
输出:
LEVEL | COL1 | COL2 | PATH
----: | :--- | :--- | :--------------------
1 | a | b | ->(a,b)
2 | a | b | ->(a,b)->(a,b)
3 | a | b | ->(a,b)->(a,b)->(a,b)
3 | c | d | ->(a,b)->(a,b)->(c,d)
2 | c | d | ->(a,b)->(c,d)
3 | a | b | ->(a,b)->(c,d)->(a,b)
3 | c | d | ->(a,b)->(c,d)->(c,d)
1 | c | d | ->(c,d)
2 | a | b | ->(c,d)->(a,b)
3 | a | b | ->(c,d)->(a,b)->(a,b)
3 | c | d | ->(c,d)->(a,b)->(c,d)
2 | c | d | ->(c,d)->(c,d)
3 | a | b | ->(c,d)->(c,d)->(a,b)
3 | c | d | ->(c,d)->(c,d)->(c,d)
你得到 14 行,因为你在第 1 级得到 2 行(每个输入行组合一行),然后在第 2 级得到 4 行(每个输入行对应第 1 级行的每个行),然后 8 行在级别 2(每个级别 2 行的每个输入行一个)并且您的输出呈指数增长。
db<>fiddle here
我已经成功地理解了按级别连接如何与下面的示例一起工作:
SELECT
level,
t.*
FROM
(
SELECT
'a' AS col1,
'b' AS col2
FROM
dual
UNION ALL
SELECT
'c',
'd'
FROM
dual
) t
CONNECT BY
level <= 3
但是,我很难理解 'start with' 和 'prior' 的概念以及它们在现实生活中的用例。有人可以使用提供的示例指导我吗?
如果你们有 parent/child 关系:
CREATE TABLE t ( parent, child ) AS
SELECT 'a', 'b' FROM dual UNION ALL
SELECT 'b', 'c' FROM dual UNION ALL
SELECT 'c', 'd' FROM dual UNION ALL
SELECT 'd', 'e' FROM dual;
并且你想获取从b
开始的家谱并获取所有后代,那么你可以:
SELECT level,
t.*
FROM t
START WITH parent = 'b'
CONNECT BY PRIOR child = parent
输出:
LEVEL | PARENT | CHILD ----: | :----- | :---- 1 | b | c 2 | c | d 3 | d | e
第 1 级以 b
开头,然后第 2 级有 b
的 child c
然后第 3 级有 b
的 child 的 child (grandchild) d
并且它们都通过 PRIOR
child
是(当前)parent
的关系连接].
有关如何获得不同关系的更多示例,请参见
顺便说一句,您在问题中的示例有点令人困惑,因为它找到了深度为 3 的递归的所有路径。如果您使用 SYS_CONNECT_BY_PATH
显示它通过数据所采用的路径,那么您会得到一个更好的主意:
SELECT level,
t.*,
SYS_CONNECT_BY_PATH( '('||col1||','||col2||')', '->' ) AS path
FROM (
SELECT 'a' AS col1, 'b' AS col2 FROM dual UNION ALL
SELECT 'c', 'd' FROM dual
) t
CONNECT BY level <= 3
输出:
LEVEL | COL1 | COL2 | PATH ----: | :--- | :--- | :-------------------- 1 | a | b | ->(a,b) 2 | a | b | ->(a,b)->(a,b) 3 | a | b | ->(a,b)->(a,b)->(a,b) 3 | c | d | ->(a,b)->(a,b)->(c,d) 2 | c | d | ->(a,b)->(c,d) 3 | a | b | ->(a,b)->(c,d)->(a,b) 3 | c | d | ->(a,b)->(c,d)->(c,d) 1 | c | d | ->(c,d) 2 | a | b | ->(c,d)->(a,b) 3 | a | b | ->(c,d)->(a,b)->(a,b) 3 | c | d | ->(c,d)->(a,b)->(c,d) 2 | c | d | ->(c,d)->(c,d) 3 | a | b | ->(c,d)->(c,d)->(a,b) 3 | c | d | ->(c,d)->(c,d)->(c,d)
你得到 14 行,因为你在第 1 级得到 2 行(每个输入行组合一行),然后在第 2 级得到 4 行(每个输入行对应第 1 级行的每个行),然后 8 行在级别 2(每个级别 2 行的每个输入行一个)并且您的输出呈指数增长。
db<>fiddle here