Проблемы с подзапросом , связанные с Oracle
-
20-09-2019 - |
Вопрос
У меня есть этот запрос:
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
s со временем я пытаюсь использовать внутренние коррелированные подзапросы, чтобы гарантировать, что acc_num
возвращается ТОЛЬКО в том случае, если это Самые новые owner
является 12345678
.Естественно, это не работает (иначе я бы не публиковал здесь ;) )
Oracle выдает мне сообщение об ошибке: ORA-000904 ac_outer.acc_num is an invalid identifier
.
Я думал , что ac_outer
должно быть видно соответствующим подзапросам, но по какой-то причине это не так.Есть ли способ исправить запрос, или мне нужно прибегнуть к PL / SQL для решения этой проблемы?
(Версия Oracle равна 10g)
Решение
Я не уверен, почему Питер использует аналитическую функцию Min (owner) вместо first_value(owner).Я полагаю, что последнее дает вам то, что вам нужно, в то время как min (владелец) дает вам "минимального" владельца.Со всем остальным в запросе я согласен:
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;
Другие советы
Я не понимаю, для чего тебе нужно 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
, которые затем могут быть сравнены во внешнем запросе.
Я думаю, что вы теряете область видимости псевдонима "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;
вы должны использовать аналитическую функцию oracle, чтобы сделать это, используя partition by
Вы можете заменить заказанные вами подзапросы на тот, который НЕ СУЩЕСТВУЕТ, который проверяет, есть ли другие владельцы позже.