为什么 Oracle 伪列 CONNECT_BY_ISLEAF 似乎损坏了?

Why does Oracle pseudo column CONNECT_BY_ISLEAF seems broken?

首先简要描述一下我的问题

我有一个 table 包含可以在这个伪有向图中表示的数据: 我说这是一个伪图,因为我有一些“边”只在 1 个节点上连接。

每个 «边» 都被标记,并将被称为一个事件。

每个节点只包含一个ID。

Oracle (12c) table 看起来像这样: http://sqlfiddle.com/#!4/79cdb5/4/0

在 Table 我 运行 this query 我希望在其伪列 CONNECT_BY_ISLEAF 中有一个 1 的行之一有一个 0.

这是有罪的行: http://sqlfiddle.com/#!4/79cdb5/3/2

我完全无法理解为什么 oracle 不认为这一行明明是叶子。

table 数据的描述

在 table 中,我使用每一行代表一个事件(或图边)加上它所连接的节点。

VUID 列是“上一个”节点,AUID 是“步骤”,EVENT 是事件标签,NEW_VUID 是“下一个”节点。

事件 D 和 U 的例外情况只有 1 个节点与其连接,并且该节点将始终位于 VUID 列中(即使对于 D 事件,该节点是“下一个”节点)。

错误请求的描述和目的

在这里,我将仅提供一些有关我正在执行的请求的背景信息

我的最终目标是根据 Table 中的数据重新创建此图表。 为此,我将按步骤进行:

  1. 构建 «forward» 树,每个根必须是具有 D «edge» 的节点
  2. 构建 «reverse» 树,每个根都是没有子节点的节点
  3. “合并”所有相关的树,最终得到想要的图。最终图表应该接近这个问题开头显示的图表。

在第 1 步中。我应该得到如下所示的前向树:

要使用 oracle 创建树,我认为最简单的方法是进行正确的分层查询,然后使用伪列 SYS_CONNECT_BY_PATH 并在 CONNECT_BY_ISLEAF = 1 上进行过滤,这是因为仅使用叶子加上每个叶子的路径很容易重新创建树。

但是我被卡住了,因为出于某种原因我不明白 Oracle 没有像我一样考虑所有的叶子。 包含节点 88888 的叶子未考虑

我没有花时间完全理解您的数据模型,并且建议如果 table 中没有某种主键,您可能难以以可理解的方式实现您的目标。 CONNECT BY 是 Oracle 中更高级的查询形式之一,具有传统的 PRIOR t.id = t.parent_id 关系使其更容易。

无论如何,您发现结果令人困惑的原因是您的数据中有这一行:

into TEST_HISTORY values (88888, 3, 'U', null)

它是您认为是叶子的行的 "child",这使得该行实际上根本不是叶子。

运行 您的查询没有 WHERE 子句,您应该会看到它。 CONNECT BY 发生在 之前 WHERE 子句。过滤掉 WHERE 子句中的叶子不会使它们的 now-childless parents 变成叶子。