Oracle - коррелированные проблемы подзапроса - PullRequest
2 голосов
/ 18 марта 2010

У меня есть этот запрос:

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;

Идея состоит в том, чтобы получить все acc_num s (не первичный ключ) из ac_tab, которые имеют owner из 1234567.

Поскольку acc_num в ac_tab со временем могло измениться owner с, я пытаюсь использовать внутренние коррелированные подзапросы, чтобы гарантировать, что acc_num будет возвращен ТОЛЬКО, если самый последний owner - это 12345678. Естественно, это не работает (или я не буду публиковать здесь;))

Oracle выдает мне ошибку: ORA-000904 ac_outer.acc_num is an invalid identifier.

Я думал, что ac_outer должны быть видны коррелированным подзапросам, но по какой-то причине это не так. Есть ли способ исправить запрос, или мне нужно прибегнуть к PL / SQL, чтобы решить эту проблему?

(версия Oracle - 10 г)

Ответы [ 5 ]

6 голосов
/ 18 марта 2010

Я не уверен, почему Питер использует аналитическую функцию 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;
4 голосов
/ 18 марта 2010

Я не вижу, для чего вам нужен dbms_random.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;

Подзапрос дает вам владельца и самого последнего владельца на acc_num, которые затем можно сравнить во внешнем запросе.

2 голосов
/ 18 марта 2010

Я думаю, что вы теряете область действия для псевдонима "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 голос
/ 18 марта 2010

вы должны использовать аналитическую функцию оракула, чтобы сделать это с помощью раздела

0 голосов
/ 18 марта 2010

Вы можете заменить ваши заказанные подзапросы одним НЕ СУЩЕСТВУЮЩИМ, который проверяет, есть ли другие владельцы на более поздний срок.

...