【问题标题】:Oracle - correlated subquery problemsOracle - 相关子查询问题
【发布时间】:2010-03-17 21:45:17
【问题描述】:

我有这个问题:

select acc_num
from (select distinct ac_outer.acc_num, ac_outer.owner
       from ac_tab ac_outer
       where (ac_outer.owner = '1234567')
             and ac_outer.owner = (select sq.owner
                                      from (select a1.owner
                                             from ac_tab a1
                                             where a1.acc_num = ac_outer.acc_num /*This is the line that gives me problems.*/
                                             order by a1.a_date desc, a1.b_date desc, a1.c_date desc) sq
                                      where rownum = 1)
       order by dbms_random.value()) subq
order by acc_num;

我们的想法是从ac_tab 中获取所有acc_nums(不是主键),它们具有owner1234567

由于ac_tab 中的acc_num 可能会随着时间的推移而更改owners,因此我正在尝试使用内部相关子查询来确保仅在最新时返回acc_num em> owner12345678。自然,它不起作用(或者我不会在这里发帖;))

Oracle 给我一个错误:ORA-000904 ac_outer.acc_num is an invalid identifier

我认为ac_outer 应该对相关子查询可见,但由于某种原因它不是。有没有办法修复查询,还是我必须求助于 PL/SQL 来解决这个问题?

(Oracle 版本为 10g)

【问题讨论】:

    标签: sql oracle analytics correlated-subquery


    【解决方案1】:

    我不确定 Peter 为什么使用 Min(owner) 分析函数而不是 first_value(owner)。我相信后者给了你你需要的东西,而 min(owner) 给了你“最小”的所有者。我同意查询中的所有其他内容:

    Select Distinct acc_num
    From (
          Select
                acc_num,
                owner,
                first_value(owner) Over ( Partition By acc_num
                      Order By a_date Desc, b_date Desc, c_date Desc
                    ) recent_owner
          From ac_tab
         )
    Where owner = '1234567'
          And owner = recent_owner
    Order By acc_num;
    

    【讨论】:

    • 我需要对结果进行更多分析,但这似乎给了我想要的东西。我真的需要更多地了解分析函数!
    【解决方案2】:

    我看不出您需要 dbms_random.value() 做什么,但使用 analytic functions 的以下查询应该会给您预期的结果:

    Select Distinct acc_num
    From (
      Select
        acc_num,
        owner,
        First_Value(owner) Over ( Partition By acc_num
                                  Order By a_date Desc, b_date Desc, c_date Desc
                                ) recent_owner
      From ac_tab
    )
    Where owner = '1234567'
      And owner = recent_owner
    Order By acc_num;
    

    子查询为您提供每个 acc_num 的所有者和最近的所有者,然后可以在外部查询中进行比较。

    【讨论】:

    • 忽略dbms_random.value(),我正在用它测试其他东西。 ;)
    【解决方案3】:

    我认为通过在子查询中嵌套两个深度,您正在失去“AC_OUTER”别名的范围。我显然不知道您的架构,但会依赖 max(date) 来处理任何排序操作和 rownum。你为什么不尝试这样的事情:

    select ac_outer.acc_num, ac_outer.owner, max(a1.adate), max(a1.b_date), max(a1.c_date)
    from   ac_tab "AC_OUTER"
    where  ac_outer.owner = '1234567'
    group by ac_outer.owner, ac_outer.acc_num;
    

    【讨论】:

    • 你是对的,超出范围,因为超过 1 个级别。这就是代码无法按原样运行的原因。
    • 你的意思是我应该用这个替换最里面的查询?不确定如何将其集成到查询的其余部分中(并且单独运行它不会给出正确的结果)。我认为您在范围界定问题上绝对是正确的,但我曾期望所有外部查询对最里面的查询都是可见的,但看起来嵌套查询仅对直接嵌套在其中的查询可见。跨度>
    【解决方案4】:

    你应该使用 oracle 分析函数来使用 partition by 来做到这一点

    【讨论】:

      【解决方案5】:

      您可以用一个 NOT EXISTS 替换您的有序子查询,以在以后检查是否有其他所有者。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-17
        • 1970-01-01
        • 2020-11-15
        相关资源
        最近更新 更多