(Oracle)SQL迭代自连接,直到满足条件

时间:2016-10-07 10:03:31

标签: oracle recursion oracle12c

让我们假设我有这样的样本数据:

start   end
1       2
2       3
3       4
4       5
5       4
4       3
3       2
2       1  
1       7
7       8
9       10

如果我想获得以下结果,如何构建select语句:
如果start = 1且end = 5:

1       2
2       3
3       4
4       5

如果start = 1且end = 4:

1       2
2       3
3       4

如果start = 9且end = 11:

no result

谢谢!

3 个答案:

答案 0 :(得分:0)

假设您的数据创建的图表采用树形结构:

ISubDependencyResolver

答案 1 :(得分:0)

select *
from 
(
  SELECT * 
  FROM t
  start with "end" = 5  ------------> desired end
  connect by prior "start" =  "end"
)  
where 
  "start" >= 1 ---------------------> desired start
order by "start"  
;

答案 2 :(得分:0)

从后代到祖先的工作通常更容易(更快),因为在任何地方都没有分支。从节点到其子节点工作更昂贵,因为可能有许多分支要访问。因此,对于快速回答,最好从后代开始,处理树,在达到所需的祖先时停止递归查询,然后简单地检查最后一个祖先是否是所需的祖先。

如果您有大量数据并且性能可能很重要,您可能需要尝试不同的解决方案,看看哪种解决方案最适合您。

在下面的解决方案中:祖先和:后代是绑定变量 - 它们在应用程序中分配了值。如果您使用SQL Developer或Toad,则可以在尝试运行查询时轻松地为它们分配值。

with
     prep ( s, e , lvl ) as (
            select "start", "end", level as lvl 
            from   table_name
            connect by prior "start"  = "end"
                   and prior "start" != :ancestor
            start with "end" = :descendant
     )
select s as "start", e as "end"
from   prep
where  (select max(s) keep (dense_rank last order by lvl) from prep) = :ancestor
order by lvl desc
;