Oracle相关的子查询问题

时间:2010-03-17 21:45:18

标签: sql oracle analytics correlated-subquery

我有这个问题:

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;

我们的想法是从[{1}}获取所有acc_num个(不是主键),其中ac_tabowner

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

Oracle给了我一个错误:12345678

我认为相关子查询应该可以看到ORA-000904 ac_outer.acc_num is an invalid identifier,但由于某种原因,它不是。有没有办法修复查询,还是我不得不求助于PL / SQL来解决这个问题?

(Oracle verison是10g)

5 个答案:

答案 0 :(得分:6)

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

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;

答案 1 :(得分:4)

我看不到您需要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的所有者和最新所有者,然后可以在外部查询中对其进行比较。

答案 2 :(得分:2)

我认为你通过在你的子查询中嵌套两个深度来减少“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;

答案 3 :(得分:1)

你应该使用oracle分析函数来使用分区

来完成这项工作

答案 4 :(得分:0)

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