CONNECT BY 只允许一个周期

CONNECT BY allowing only one cycle

假设我有以下 table

  Row_ID | SourceId | TargetId
---------|----------|----------
    1    |    1     |    2
    2    |    2     |    3
    3    |    2     |    4
    4    |    4     |    5
    5    |    5     |    6
    6    |    6     |    5

我必须将所有这些行都带入我的查询中,因为它们都是相连的。 但是,当我这样做时:

SELECT Row_ID
FROM   MyTable
START WITH SourceId = 1
CONNECT BY NOCYCLE PRIOR TargetId = SourceId

它不会将 Row_ID 等于 6 的行带入。

我认为是因为 NOCYCLE 关键字。但是如果我把它取下来,查询就不起作用,因为那里有一个循环。

我想设置一个可以给我带来一切的查询。你们有什么想法吗?

我刚刚找到了解决方案。

SELECT myRowId
FROM   myTable
START WITH SourceId = 1
CONNECT BY NOCYCLE PRIOR TargetId = SourceId  or  TargetId = PRIOR SourceId

分享给大家。谢谢。

那行得通。但是,您实际上并不需要 CONNECT BY 来满足您的需求,这并不是什么问题。

这是一个不使用 CONNECT BY

的替代版本
select *
  from test et 
 where exists(select 1
                from test it
               where et.targetId = it.sourceId OR it.targetId = et.sourceId)
 order by row_id;

通过计算出哪些行彼此指向彼此,它几乎应用了相同的想法

根据包含在 CONNECT BY 子句中的列中的值检测循环,具体来说,仅那些受 PRIOR 运算符约束的列。

在您的示例中,即使这个附加条件(如下)看起来应该没有效果,但它确实有效果。只要尝试一下,您就会看到。添加

and PRIOR Row_ID IS NOT NULL

当然,没有 Row_ID 是空的,所以这不会改变逻辑;但现在 Row_ID 的值已添加到确定循环是否存在时考虑的值中,因此您将能够获取所有行。

(注意 - 我刚刚编辑了我的答案,将 RowID 更改为 Row_ID 以避免与 Oracle 保留字发生冲突。)