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用法