Альтернатива функции WINDOW в предложении HAVING - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь получить самую старую дату обработки для каждого продукта, как это:

select prod_id, prod_name, prod_date, min(prod_date) over (partition by prod_id) as min_prod_date
from dim_product
where prod_name in ('xxx', 'yyy', 'zzz')
having prod_date = min_prod_date

Это дает мне ошибку:

ORA-00904: "min_prod_date" : неверный идентификатор

Итак, я попытался использовать функцию min () в предложении has, которая выдала мне ошибку:

ORA-30483: оконные функции не разрешены здесь

В качестве альтернативы я изменил свой запрос следующим образом:

with temp as(
select prod_id, prod_name, prod_date, min(prod_date) over (partition by prod_id) as min_prod_date
    from dim_product
    where prod_name in ('xxx', 'yyy', 'zzz')
    having prod_date = min_prod_date))
select * from temp where prod_date = min_prod_date

Это правильный способ сделать что-то или есть другой эффективный метод?

Ответы [ 3 ]

0 голосов
/ 19 февраля 2020

Звучит как агрегация:

select prod_name, min(prod_date)
from dim_product
where prod_name in ('xxx', 'yyy', 'zzz')
group by prod_name;
0 голосов
/ 19 февраля 2020

Вы можете использовать свой запрос как подзапрос и получить желаемый результат следующим образом:

Select prod_id, prod_name, prod_date
From
(select prod_id, prod_name, prod_date, 
        min(prod_date) over (partition by prod_id) as min_prod_date
from dim_product
where prod_name in ('xxx', 'yyy', 'zzz'))
Where prod_date = min_prod_date

Cheers !!

0 голосов
/ 19 февраля 2020

Один метод использует rank() в подзапросе:

select *
from (
    select 
        prod_id, 
        prod_name, 
        prod_date, 
        rank() over(partition by prod_id order by prod_date) rn
    from dim_product
    where prod_name in ('xxx', 'yyy', 'zzz')
) t
where rn = 1

В качестве альтернативы вы можете также рассмотреть возможность фильтрации с коррелированным подзапросом:

select prod_id, prod_id, prod_date
from dim_product d
where d.prod_name in ('xxx', 'yyy', 'zzz') and d.prod_date = (
    select min(d1.prod_date)
    from dim_product d1
    where d1.prod_id = d.prod_id and d1.prod_name in ('xxx', 'yyy', 'zzz')
)

Для повышения эффективности в последний запрос, вы хотите индекс на (prod_name, prod_id, prod_date).

...