2010-03-17 3 views
2

У меня есть этот запрос:Oracle - коррелировали проблемы подзапрос

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 с (не первичный ключ) из 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 verison является 10г)

ответ

6

Я не уверен, почему Питер использует аналитическую функцию Min (owner) вместо 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; 
+0

+1: Вы правы, спасибо за исправление. Не знаю, что я думал ... –

+0

Мне нужно сделать немного больше анализа результатов, но это, кажется, дает мне то, что я хочу. Мне действительно нужно больше узнать об аналитических функциях! – FrustratedWithFormsDesigner

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; 
+1

Вы правы, вне сферы действия, потому что более 1 уровня. Вот почему код не будет работать как есть. –

+0

Вы имеете в виду, что я должен заменить самый внутренний запрос этим? Не уверен, как интегрировать это в остальную часть запроса (и запуск его сам по себе не дает правильного результата). Я думаю, что вы определенно правы в вопросе определения области обзора, хотя, но я ожидал, что все внешние запросы будут видны самому внутреннему запросу, но похоже, что вложенный запрос доступен только для запроса, вложенного непосредственно в него. – FrustratedWithFormsDesigner

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, которые затем могут быть сопоставлены во внешнем запросе.

+0

Игнорировать 'dbms_random.value()', я тестировал что-то еще с этим. ;) – FrustratedWithFormsDesigner

+0

Вот что я сделал :) Так это работает для вас? –

0

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

Смежные вопросы