Незабавната грешка е причинена от наличието на два псевдонима, дадени на резултата от конкатенацията:Имате AS LIST as ids
. Не можете да дадете два псевдонима на резултата от изчисление. Ако искате новосъздадената таблица да има колона LIST
след това изтрийте as ids
и обратно.
Тогава ще попаднете на друга грешка:опитвате се да ORDER BY t1.a
в агрегацията. Това няма да работи; не можете да поръчате по CLOB в XML агрегацията. Наистина ли ви интересува в какъв ред се случва агрегацията? Ако не го направите, сменете на ORDER BY NULL
. Ако ви пука, имате проблем, тъй като в Oracle order_by_clause
просто не може да подреди чрез CLOB израз. Ще трябва да създадете отделна колона за подреждане чрез използване на други методи.
В решението като цяло няма нужда от клаузата WITH. Където и да се позовавате на "input_strings" в заявката (различно от клаузата WITH), просто напишете "table_expressions".
РЕДАКТИРАНЕ
Ето как това може да бъде накарано да работи. Първо ще покажа инструкциите CREATE TABLE. Ще приема, че table_expressions
има колона CLOB с низове за търсене и че в тази колона НЯМА ДУБЛИКАТИ. Въпреки това таблицата също се нуждае от отделен първичен ключ от тип данни, който не е LOB или друг дълъг, нестандартен тип. Използвам NUMBER за това.
След това обобщавам по тази колона с първичен ключ. Уви, не мога да избера едновременно низа за търсене. Мога да SELECT MAX(t2.a)
но това също не работи с CLOB стойности! Вместо това имам нужда от допълнително присъединяване, за да съпоставя първичния ключ с низа за търсене. (За съжаление заявката ще отнеме много повече време поради това...)
При агрегирането сортирам по първите 4000 знака от стойността на низа от колона a
. Това не е толкова добро, колкото сортирането по целия входен низ, но все пак е по-добро от подреждането по NULL.
create table a_x ( a, b ) as
select to_clob('atveroeosipsumloremipsumdolor'), 1 from dual union all
select to_clob('stetclitakasdtest') , 2 from dual union all
select to_clob('noseatakimataatveroeosipsum') , 3 from dual union all
select to_clob('loremipsumdolor') , 4 from dual union all
select to_clob('consetetursadipscingelitr') , 5 from dual
;
create table table_expressions ( a, pk ) as
select to_clob('atveroeosipsum') , 10 from dual union all
select to_clob('test') , 11 from dual union all
select to_clob('stetclitakasd') , 12 from dual union all
select to_clob('noseatakimata') , 13 from dual union all
select to_clob('loremipsumdolor') , 14 from dual union all
select to_clob('consetetursadipscingelitr'), 15 from dual
;
create table a_y as
select te.a, s.ids
from table_expressions te
join
(select t2.pk, RTRIM(XMLAGG(XMLELEMENT(E,t1.a,',').EXTRACT('//text()')
ORDER BY cast(t1.a as varchar2(4000))).GetClobVal(),',') as ids
from a_x t1
join table_expressions t2
on t1.a like '%' || t2.a || '%'
group by t2.pk
) s
on te.pk = s.pk
;
Сега нека проверим какво имаме:
select * from a_y;
A IDS
------------------------- ---------------------------------------------------------
atveroeosipsum atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test stetclitakasdtest
stetclitakasd stetclitakasdtest
noseatakimata noseatakimataatveroeosipsum
loremipsumdolor atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr consetetursadipscingelitr
РЕДАКТИРАНЕ #2
Ако трябва да свържете идентификаторите от таблица a_x
(колона b
), а не самите CLOB, след това заменете t1.a
с t1.b
(и в ORDER BY
клауза на XMLAGG
, нямате нужда от cast
, просто order by t1.b
).
drop table a_y purge;
create table a_y as
select te.a, s.ids
from table_expressions te
join
(select t2.pk, RTRIM(XMLAGG(XMLELEMENT(E,t1.b,',').EXTRACT('//text()')
ORDER BY t1.b).GetClobVal(),',') as ids
from a_x t1
join table_expressions t2
on t1.a like '%' || t2.a || '%'
group by t2.pk
) s
on te.pk = s.pk
;
select * from a_y;
A IDS
------------------------- ---
atveroeosipsum 1,3
test 2
stetclitakasd 2
noseatakimata 3
loremipsumdolor 1,4
consetetursadipscingelitr 5