【问题标题】:How to use select result as input for the second select (like foreach)?如何使用选择结果作为第二次选择的输入(如 foreach)?
【发布时间】:2015-10-01 11:28:21
【问题描述】:

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

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

结果 - 条件是我只想要根名称 = item1 的树

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

基本上它是一个树结构,我想获取树中的所有行(两层深),从根开始。结果中缺少第 5 项,因为它在第三级中,第 6 项因为它是不同的树。

【问题讨论】:

  • 是的,它被称为相关子查询
  • 编辑您的问题并提供示例数据和所需结果。
  • 也许你只是在一个连接之后,而不是一个相关的子查询?如果没有 Gordon 要求的信息,很难猜出您的意思。
  • @Boneist 我添加了示例

标签: sql oracle


【解决方案1】:

看起来您正在执行分层查询:

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

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

这就是为什么我生成“max_lvl”列的原因,它只是找到该特定分支的最深层次,然后添加外部查询以过滤掉只有顶层的分支。

如果不是这样,那么您必须更具体地说明为什么您不希望它出现在结果中的逻辑。

【讨论】:

  • OP 不想要item6,因为I want only tree where root name = item1。如果您使用START WITH name = 'item1',那么您可以大大简化您的查询。
  • 是的,是的;目前尚不清楚为什么 OP 只想要 item1,因此我的查询
【解决方案2】:

您可以使用分层查询:

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;

对我来说,不清楚为什么不希望显示“item6”,这对我来说不合逻辑。无论如何,您可以通过以下方式实现它:

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

【讨论】:

    【解决方案3】:

    SQL Fiddle

    Oracle 11g R2 架构设置

    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;
    

    查询 1

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

    Results

    | PARENT_NAME |  NAME |
    |-------------|-------|
    |      (null) | item1 |
    |       item1 | item2 |
    |       item2 | item4 |
    |       item1 | item3 |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 2021-09-29
      • 2013-02-02
      • 2022-01-22
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多