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

Ckl*_*kln 5 sql oracle graph hierarchical-query oracle12c

首先简要介绍一下我的问题

我有一个包含数据的表,可以在这个伪有向图中表示: 伪图图像 我说这是一个伪图,因为我有一些«edge»,只连接在一个节点上.

每个«edge»都被标记,并将被视为一个事件.

每个节点只包含一个ID.

Oracle(12c)表如下所示:http: //sqlfiddle.com/#!4/79cdb5/4/0

在表上我运行了这个查询 ,我期望在其伪列CONNECT_BY_ISLEAF中有1的行之一而不是0.

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

我完全无法理解为什么oracle不认为这行显然是一个叶子.

表数据的描述

在表格中,我使用的每一行代表一个事件(或图形边缘)以及它所连接的节点.

VUID列是"上一个"节点,AUID是"步骤",EVENT是事件标签,NEW_VUID是"下一个"节点.

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

故障请求的描述和目标

在这里,我将给出一些关于我正在做的请求的背景信息

我的最终目标是根据表格中的数据重新创建此图表.为此我继续前进:

  1. 构建«forward»树,每个根必须是带有D«edge的节点»
  2. 构建«reverse»树,每个根都是没有子节点的节点
  3. 将所有相关的树"合并"在一起,最终得到想要的图形.最终图表应该接近此问题开头所示的图表.

在第1步中,我应该看到这样的前向树: 首先计算前向树 第二个计算的前向树

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

但是我被困了,因为由于某些原因我不明白Oracle不会像我一样考虑所有的方式.包含节点88888的叶子没有考虑

Mat*_*eak 5

我没有花时间完全理解您的数据模型,并建议您可能无法以可理解的方式实现目标,而无需在表格中使用某种主键. CONNECT BY是Oracle中更高级的查询表单之一,具有传统PRIOR t.id = t.parent_id关系使其更容易.

无论如何,您发现混淆的结果的原因是因为您的数据中包含以下行:

into TEST_HISTORY values (88888, 3, 'U', null)
Run Code Online (Sandbox Code Playgroud)

它是你认为是一片叶子的行的"孩子",使得该行实际上根本不是叶子.

在没有该WHERE子句的情况下运行您的查询,您应该看到它.在CONNECT BY发生之前WHERE条款.过滤掉WHERE条款中的叶子并不能使他们现在没有孩子的父母留下来.