Это сложный вопрос.Вот пошаговое описание того, как я поступил.
Первая часть состоит в разбиении каждого значения на строки с использованием разделителя #
.Для этого мы используем REGEXP_SUBSTR()
вместе с CONNECT BY
для генерации рекурсии.
select trim(regexp_substr(trxn_a,'[^#]+', 1, level) ) trxn_a, level
from mytable
connect by regexp_substr(trxn_a, '[^#]+', 1, level) is not null
Затем нам нужно разобрать каждое результирующее значение в столбцы .Это можно сделать просто с помощью серии REGEXP_SUBSTR()
.Особое внимание следует уделить столбцу, который содержит значения суммы, которые содержат нецифровые символы ('$5,000'
): необходимо удалить недопустимые символы, чтобы впоследствии значение можно было рассматривать как число.
Примечание: для вашей цели вам не нужно восстанавливать все 4 столбца из значения (достаточно указать дату и сумму);Я показываю все столбцы на случай, если вам когда-нибудь понадобится доступ к другому.
select
'ta' src,
regexp_substr(trxn_a,'[^~]+', 1, 1) tdate,
regexp_substr(trxn_a,'[^~]+', 1, 2) ttype,
replace(regexp_substr(trxn_a,'[^$~]+', 1, 3), ',', '') tamount,
regexp_substr(trxn_a,'[^~]+', 1, 4) tuser
from (
select trim(regexp_substr(trxn_a,'[^#]+', 1, level) ) trxn_a, level
from mytable
connect by regexp_substr(trxn_a, '[^#]+', 1, level) is not null
)
Каждый столбец в исходной таблице (trxn_a
, trxn_b
) должен обрабатываться отдельно, так как каждое значениегенерирует случайное количество записей.Результаты могут быть UNION
ed, а затем внешний запрос выполняет условное агрегирование:
Окончательный запрос:
with t as (
select
'ta' src,
regexp_substr(trxn_a,'[^~]+', 1, 1) tdate,
regexp_substr(trxn_a,'[^~]+', 1, 2) ttype,
replace(regexp_substr(trxn_a,'[^$~]+', 1, 3), ',', '') tamount,
regexp_substr(trxn_a,'[^~]+', 1, 4) tuser
from (
select trim(regexp_substr(trxn_a,'[^#]+', 1, level) ) trxn_a, level
from mytable
connect by regexp_substr(trxn_a, '[^#]+', 1, level) is not null
)
union all
select
'tb' src,
regexp_substr(trxn_b,'[^~]+', 1, 1) tdate,
regexp_substr(trxn_b,'[^~]+', 1, 2) ttype,
replace(regexp_substr(trxn_b,'[^$~]+', 1, 3), ',', '') tamount,
regexp_substr(trxn_b,'[^~]+', 1, 4) tuser
from (
select trim(regexp_substr(trxn_b,'[^#]+', 1, level) ) trxn_b, level
from mytable
connect by regexp_substr(trxn_b, '[^#]+', 1, level) is not null
)
)
select
tdate,
SUM(DECODE(src, 'ta', tamount, 0)) trxn_amt_a,
SUM(DECODE(src, 'tb', tamount, 0)) trxn_amt_b
from t
group by tdate;
С вашими тестовыми данными, эта демонстрация в БДСкрипка доходность:
TDATE TRXN_AMT_A TRXN_AMT_B
2019-01-25 5000 4500
2019-01-26 1000 1000