У меня есть две таблицы:
1) Операции (ключ = id + тип)
id |date |type |purpose | amount
------------------------------------------------------------
1001 |21.01.2020 | IN | CCARD202011WSX | 100
------------------------------------------------------------
1002 |11.01.2020 | OUT | RETAIL OPERATION | 10
------------------------------------------------------------
1003 | 12.01.2020 | OUT | INS1230TFR | 20
------------------------------------------------------------
1004 | 10.01.2020 | IN | INS1241TFP | 15
------------------------------------------------------------
Эта таблица составляет около 100 миллионов строк в день.
2) Категория
priority |type |purpose |category
--------------------------------------------------------
1 | IN | CCARD% | corporate
--------------------------------------------------------
1 | ? | RETAIL% | retail
--------------------------------------------------------
5 | OUT | ? | corporate
--------------------------------------------------------
10 | ? | ? | retail
--------------------------------------------------------
Эта таблица содержит около 100 строк.
? - любой символ
Взять категорию с минимальным приоритетом.
Необходимо определить категорию для каждой операции. Обязательный набор:
id |date |type |purpose | amount | category
-----------------------------------------------------------------------------
1001 |21.01.2020 | IN | CCARD202011WSX | 100 | corporate
-----------------------------------------------------------------------------
1002 |11.01.2020 | OUT | RETAIL OPERATION | 10 | retail
-----------------------------------------------------------------------------
1003 | 12.01.2020 | OUT | INS1230TFR | 20 | corporate
------------------------------------------------------------------------------
1004 | 10.01.2020 | IN | INS1241TFP | 15 | retail
------------------------------------------------------------------------------
Я сделал запрос, который работает в любой день, но не работает в течение месяца.
select /*+MAPJOIN(b)*/
t.id,t.date,t.type,t.purpose,t.amount,t.category
from
(
select min(t.rn) over (partition by t.id,t.type) as min_rn,t.* from
(
select a.*,
case when
(upper(a.type) like b.type or b.type = '?')
and
(upper(a.purpose) like b.purpose or b.purpose = '?')
then b.category else null as category,
row_number() over (partition by a.id,a.type order by b.priority) as rn
from Operations a cross join Category b
)t where t.marker is not null
)t where t.rn = t.min_rn
Есть ли другие способы решения этой проблемы?