如何使用选择结果作为第二个选择的输入(如foreach)?

时间:2015-10-01 11:28:22

标签: sql oracle

这是我想要实现的,在伪代码中

part1 = select from foo ...
part2 = init empty
foreach row in part1
  part2 += select from foo where row.something as condition in here 
union part1, part2

是否可以在一个查询中执行此操作?

这是结构

parent_name | name
------------+-------
null        | item1  # root
item1       | item2  # first level
item1       | item3  # first level
item2       | item4  # second level
item4       | item5  # third level
null        | item6  # another root

结果 - 条件是我只想要树名为root name = item1

parent_name | name
------------+-------
null        | item1  
item1       | item2
item1       | item3  
item2       | item4

基本上它是一个树形结构,我希望得到树中的所有行(两层深),从根开始。结果中缺少Item5,因为它在第三级和item6中,因为它是不同的树。

3 个答案:

答案 0 :(得分:6)

看起来像是在分层查询之后:

with sample_data as (select null parent_name, 'item1' name from dual union all
                     select 'item1' parent_name, 'item2' name from dual union all
                     select 'item1' parent_name, 'item3' name from dual union all
                     select 'item2' parent_name, 'item4' name from dual union all
                     select 'item4' parent_name, 'item5' name from dual union all
                     select null parent_name, 'item6' name from dual)
select parent_name,
       name
from   (select parent_name,
               name,
               level lvl,
               max(level) over (partition by connect_by_root(name)) max_lvl
        from   sample_data sd
        connect by prior name = parent_name
                   and level <= 3
        start with parent_name is null)
where max_lvl > 1;

PARENT_NAME NAME 
----------- -----
            item1
item1       item2
item2       item4
item1       item3

N.B。我不能完全确定你为什么不想在结果中看到item6,所以我认为这是因为它没有任何子行。

这就是为什么我生成&#34; max_lvl&#34; column,它只查找该特定分支的最深层,然后添加外部查询以过滤掉仅具有顶层的分支。

如果情况并非如此,那么您必须更加具体地说明您在结果中不想要它的原因。

答案 1 :(得分:1)

您可以使用分层查询:

SELECT parent_name, NAME
FROM table1
WHERE LEVEL <= 3
CONNECT BY PRIOR NAME = parent_name
START WITH parent_name IS NULL;
ORDER BY 1 NULLS FIRST;

对我而言,目前尚不清楚为什么你不想要&#34; item6&#34;要显示,这对我来说不合逻辑。无论如何,你实现了这个目标:

SELECT parent_name, NAME
FROM table1
WHERE LEVEL <= 3
CONNECT BY PRIOR NAME = parent_name
START WITH NAME = 'item1'
ORDER BY 1 NULLS FIRST;

答案 2 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

$(div2, divtemp).show();

查询1

CREATE TABLE test ( parent_name, name ) AS
          SELECT NULL,    'item1' FROM DUAL
UNION ALL SELECT 'item1', 'item2' FROM DUAL
UNION ALL SELECT 'item1', 'item3' FROM DUAL
UNION ALL SELECT 'item2', 'item4' FROM DUAL
UNION ALL SELECT 'item4', 'item5' FROM DUAL
UNION ALL SELECT NULL,    'item6' FROM DUAL;

<强> Results

SELECT *
FROM   test
WHERE  LEVEL <= 3
START WITH name = 'item1'
CONNECT BY PRIOR name = parent_name