Oracle START WITH 子句不返回根行

Posted

技术标签:

【中文标题】Oracle START WITH 子句不返回根行【英文标题】:Oracle START WITH clause returns no root rows 【发布时间】:2017-04-05 15:49:51 【问题描述】:

我在 Oracle 10g 中执行以下查询以检索分层形式的数据(完整的查询有点复杂):

SELECT LEVEL AS lvl, a.*
 FROM (
      WITH temp
        AS (...)
    SELECT id_request, subj_type, id_subj, name, flag_e,
           person_code, assoc_type, nature, parent
      FROM temp,
           (...)
    ) a
START WITH a.parent IS NULL
CONNECT BY PRIOR a.id_subj = a.parent;

这是内部选择返回的集合:

ID_REQUEST  SUBJ_TYPE   ID_SUBJ                             NAME            FLAG_E  PERSON_CODE         ASSOC_TYPE  NATURE  PARENT
91948       F           4A4BE76C44D4003CE0530AA000A6003C    John Smith      0       xxxyyy123456zzzzz   Declarant   F       NULL
91948       C           4A4BE76C44D6003CE0530AA000A6003C    Rose Anderson   0       kkkkkk654321qqqqq   NULL        F       4A4BE76C44D4003CE0530AA000A6003C

如果我运行整个查询没有 START WITH 子句我正确地得到以下结果:

LVL ID_REQUEST  SUBJ_TYPE   ID_SUBJ                             NAME            FLAG_E  PERSON_CODE         ASSOC_TYPE  NATURE  PARENT                          
1   91948       C           4A4BE76C44D6003CE0530AA000A6003C    Rose Anderson   0       kkkkkk654321qqqqq   NULL        F       4A4BE76C44D4003CE0530AA000A6003C
1   91948       F           4A4BE76C44D4003CE0530AA000A6003C    John Smith      0       xxxyyy123456zzzzz   Declarant   F       NULL                                
2   91948       C           4A4BE76C44D6003CE0530AA000A6003C    Rose Anderson   0       kkkkkk654321qqqqq   NULL        F       4A4BE76C44D4003CE0530AA000A6003C

但如果我 使用 START WITH 子句运行它,则查询不会返回任何行,而我希望有 2 行:

LVL     ID_REQUEST  SUBJ_TYPE   ID_SUBJ                             NAME            FLAG_E  PERSON_CODE         ASSOC_TYPE  NATURE  PARENT
1       91948       F           4A4BE76C44D4003CE0530AA000A6003C    John Smith      0       xxxyyy123456zzzzz   Declarant   F       NULL
2       91948       C           4A4BE76C44D6003CE0530AA000A6003C    Rose Anderson   0       kkkkkk654321qqqqq   NULL        F       4A4BE76C44D4003CE0530AA000A6003C

最奇怪的是:

    该问题仅在某些情况下出现,而查询适用于大多数情况,数据值没有太大差异; 如果我使用内部选择的结果集创建表,即使使用 START WITH 子句,相同的查询也能正常工作。

这是使用创建的表的查询:

  select LEVEL as lvl, a.*
    from (select * from test_tbl) a
   start with a.parent is null
 connect by PRIOR a.id_subj = a.parent;

似乎 START WITH 子句与 PARENT 字段中的 NULL 值不匹配。为什么会这样?

提前致谢。 最好的问候。

【问题讨论】:

似乎对我有用,从您发布的内容中模拟内部查询结果 - 我得到了两行。为了清楚起见,内部查询显示的 NULL 实际上是 null,而不是字符串 'NULL',而不是 char 或其他填充字符串值? 您需要发布足够的代码让我们了解您的问题。如果您的整个查询过于复杂而无法在此处发布,您需要编写一个重现问题的小测试用例。 @Alex Poole:是的,这些是 NULL RAW 值。我输入“NULL”这个词只是为了表明它不是空白的。我可以补充一点,我已经使用 UTL_RAW.compare 检查了它们是否被识别为 NULL。 【参考方案1】:

请尝试以下操作。 “具体化”提示很重要。

WITH
temp AS (...),
a as (
    SELECT /*+ materialize */ id_request, subj_type, id_subj, name, flag_e,
           person_code, assoc_type, nature, parent
      FROM temp,
           (...)
)
SELECT LEVEL AS lvl, a.*
 FROM a
START WITH a.parent IS NULL
CONNECT BY PRIOR a.id_subj = a.parent;

【讨论】:

接受,即使不需要使用提示。使用 WITH 子句实现“a”选择就足够了。非常感谢!

以上是关于Oracle START WITH 子句不返回根行的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 之 树查询 START WITH ... CONNECT BY ...子句

Oracle中start with...connect by子句的用法

Oracle中start with connect by prior用法

包含使用 with 子句的 sql 的 oracle 管道函数

Oracle Reports 中的从属 WITH 子句

EXISTS 不适用于 WITH 子句中的子查询