Как уже говорили другие, плохая идея хранить данные таким образом. Скорее всего, у вас может быть ввод , как это, и вам, вероятно, понадобится отображение данных, подобных этим, но вам не нужно хранить данные так, как они вводятся или отображаются .
Я собираюсь сохранить данные как отдельные LOC
элементы на основе ввода. Я предполагаю, что данные содержат только целые числа, разделенные запятыми, или пары целых чисел, разделенные дефисом. Пробелы игнорируются. Список через запятую не должен быть в любом порядке. В парах, если левое целое больше правого, я не возвращаю элемент LOC
.
create table t as
with input(id, item, item_loc) as (
select 1, 'Item-1', ' 0,1' from dual union all
select 2, 'Item-2', '0,1,2,3,4,7' from dual union all
select 3, 'Item-3', '0-48' from dual union all
select 4, 'Item-4', '0,1,2,3,4,5,6,7,8' from dual union all
select 5, 'Item-5', '1-33' from dual union all
select 6, 'Item-6', '0,1' from dual union all
select 7, 'Item-7', '0,1,5,8,7 - 11' from dual
)
select distinct id, item, loc from input, xmltable(
'let $item := if (contains($X,",")) then ora:tokenize($X,"\,") else $X
for $i in $item
let $j := if (contains($i,"-")) then ora:tokenize($i,"\-") else $i
for $k in xs:int($j[1]) to xs:int($j[count($j)])
return $k'
passing item_loc as X
columns loc number path '.'
);
Теперь, чтобы "использовать" элемент, я просто удаляю его из таблицы:
delete from t where rowid = (
select min(rowid) keep (dense_rank first order by loc)
from t
where id = 7
);
Чтобы вернуть данные в том же формате, в котором они были введены, используйте MATCH_RECOGNIZE
:
select id, item, listagg(item_loc, ',') within group(order by first_loc) item_loc
from t
match_recognize(
partition by id, item order by loc
measures a.loc first_loc,
a.loc || case count(*) when 1 then null else '-'||b.loc end item_loc
pattern (a b*)
define b as loc = prev(loc) + 1
)
group by id, item;
ID ITEM ITEM_LOC
1 Item-1 0-1
2 Item-2 0-4,7
3 Item-3 0-48
4 Item-4 0-8
5 Item-5 1-33
6 Item-6 0-1
7 Item-7 1,5,7-11
Обратите внимание, что выходные данные здесь не будут точно такими же, как входные, потому что любые последовательные целые числа будут сжаты в пару.