Страницы

Поиск по вопросам

понедельник, 20 мая 2019 г.

Группировка с зависимой максимизацией двух столбцов (без подзапросов)

Есть задача вывести все строки, группируя таблицу по столбцу t_name, при этом максимизируя по двум столбцам t_date и t_num, так что
вначале максимизируя по столбцу t_num затем оставшаяся выборка максимизируется по t_date
Вопрос: можно ли это организовать без подзапросов (например, оконными функциями или другими способами), и будет ли это работать быстрее?
Для примера
t_name t_date t_num 1 aaa 20.01.2018 3 2 aaa 03.01.2018 10 3 aaa 01.01.2018 10 4 aaa (null) 10 5 bbb 19.01.2018 1 6 bbb (null) 10
в результате максимизации по столбцу t_num останутся значения
t_name t_date t_num 2 aaa 03.01.2018 10 3 aaa 01.01.2018 10 4 aaa (null) 10 6 bbb (null) 10
затем выборку максимизируется по столбцу t_date и останутся значения
t_name t_date t_num 2 aaa 03.01.2018 10 6 bbb (null) 10
Это легко можно сделать через подзапросы
SELECT T.T_NAME, MAX(T.T_DATE) AS T_DATE, G.T_NUM FROM TEST_GROUPING T INNER JOIN ( SELECT T_NAME, MAX(T_NUM) AS T_NUM FROM TEST_GROUPING GROUP BY T_NAME ) G ON G.T_NAME = T.T_NAME AND G.T_NUM = T.T_NUM GROUP BY T.T_NAME, G.T_NUM


Ответ

Да, оконными функциями делается элементарно:
with t (t_name, t_date, t_num) as ( select 'aaa', to_date('20.01.2018', 'dd.mm.yyyy'), 3 from dual union all select 'aaa', to_date('03.01.2018', 'dd.mm.yyyy'), 10 from dual union all select 'aaa', to_date('01.01.2018', 'dd.mm.yyyy'), 10 from dual union all select 'aaa', null, 10 from dual union all select 'bbb', to_date('20.01.2018', 'dd.mm.yyyy'), 1 from dual union all select 'bbb', null, 10 from dual) select t_name, t_date, t_num from (select t_name, t_date, t_num, row_number() over (partition by t_name order by t_num desc, t_date desc nulls last) rn from t) where rn = 1
Работать тоже должно быстро, особенно если у вас есть индекс по t_num, а лучше даже по (t_num, t_date).

Комментариев нет:

Отправить комментарий