Natychmiastowy błąd jest spowodowany tym, że wynikowi konkatenacji zostały nadane dwa aliasy:Masz AS LIST as ids
. Nie możesz nadać wynikowi obliczeń dwóch aliasów. Jeśli chcesz, aby nowo utworzona tabela miała kolumnę LIST
następnie usuń as ids
i na odwrót.
Następnie napotkasz inny błąd:próbujesz ORDER BY t1.a
w agregacji. To nie zadziała; nie można zamówić przez CLOB w agregacji XML. Czy naprawdę zależy Ci, w jakiej kolejności odbywa się agregacja? Jeśli nie, zmień na ORDER BY NULL
. Jeśli Ci zależy, masz problem, ponieważ w Oracle order_by_clause
po prostu nie można uporządkować według wyrażenia CLOB. Będziesz musiał utworzyć osobną kolumnę do zamawiania innymi metodami.
W ogólnym rozwiązaniu nie ma potrzeby stosowania klauzuli WITH. Gdziekolwiek odwołasz się do „input_strings” w zapytaniu (innym niż klauzula WITH), po prostu napisz „table_expressions”.
EDYTUJ
Oto jak można to zrobić. Najpierw pokażę instrukcje CREATE TABLE. Zakładam, że table_expressions
zawiera kolumnę CLOB z ciągami wyszukiwania i że w tej kolumnie nie ma DUPLIKATÓW. Mimo to tabela wymaga również oddzielnego klucza podstawowego typu danych, który nie jest LOB ani innym długim, niestandardowym typem. Używam do tego numeru NUMBER.
Następnie agreguję według tej kolumny klucza podstawowego. Niestety, nie mogę jednocześnie wybrać ciągu wyszukiwania. Mógłbym SELECT MAX(t2.a)
ale to też nie działa z wartościami CLOB! Zamiast tego potrzebuję dalszego sprzężenia, aby dopasować klucz podstawowy do ciągu wyszukiwania. (Przepraszamy, zapytanie potrwa dłużej z tego powodu...)
W agregacji sortuję według pierwszych 4000 znaków wartości ciągu z kolumny a
. Nie jest to tak dobre, jak sortowanie według całego łańcucha wejściowego, ale wciąż jest lepsze niż porządkowanie według wartości 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
;
Sprawdźmy teraz, co mamy:
select * from a_y;
A IDS
------------------------- ---------------------------------------------------------
atveroeosipsum atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test stetclitakasdtest
stetclitakasd stetclitakasdtest
noseatakimata noseatakimataatveroeosipsum
loremipsumdolor atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr consetetursadipscingelitr
EDYCJA #2
Jeśli potrzebujesz połączyć identyfikatory z tabeli a_x
(kolumna b
), a nie same CLOB, a następnie zastąp t1.a
z t1.b
(oraz w ORDER BY
klauzula XMLAGG
, nie potrzebujesz żadnego cast
, po prostu 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