L'errore immediato è causato dall'avere due alias dati al risultato della concatenazione:Hai AS LIST as ids
. Non puoi dare due alias al risultato di un calcolo. Se vuoi che la tabella appena creata abbia una colonna LIST
quindi elimina as ids
, e viceversa.
Quindi ti imbatterai in un altro errore:stai tentando di ORDER BY t1.a
nell'aggregazione. Non funzionerà; non puoi ordinare da un CLOB nell'aggregazione XML. Ti interessa davvero in quale ordine avviene l'aggregazione? In caso contrario, passa a ORDER BY NULL
. Se ti interessa, hai un problema, poiché in Oracle un order_by_clause
semplicemente non può ordinare in base a un'espressione CLOB. Dovrai creare una colonna separata per l'ordine utilizzando altri metodi.
Nella soluzione complessiva, non è necessaria la clausola WITH. Ovunque tu faccia riferimento a "input_strings" nella query (diversa dalla clausola WITH), scrivi semplicemente "table_expressions".
MODIFICA
Ecco come potrebbe essere fatto funzionare. Per prima cosa mostrerò le istruzioni CREATE TABLE. Presumo che table_expressions
ha una colonna CLOB di stringhe di ricerca e che NON ci sono DUPLICATI in questa colonna. Anche così, la tabella necessita anche di una chiave primaria separata, di un tipo di dati che non sia LOB o un altro tipo lungo e non standard. Uso NUMBER per questo.
Quindi aggrego in base a questa colonna della chiave primaria. Purtroppo, non riesco a selezionare la stringa di ricerca allo stesso tempo. Potrei SELECT MAX(t2.a)
ma non funziona nemmeno con i valori CLOB! Invece, ho bisogno di un ulteriore join per abbinare la chiave primaria alla stringa di ricerca. (Spiacenti, la query richiederà molto più tempo per questo motivo...)
Nell'aggregazione, ordino in base ai primi 4000 caratteri del valore della stringa dalla colonna a
. Questo non è buono come ordinare per l'intera stringa di input, ma è comunque meglio che ordinare per 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
;
Ora controlliamo cosa abbiamo:
select * from a_y;
A IDS
------------------------- ---------------------------------------------------------
atveroeosipsum atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test stetclitakasdtest
stetclitakasd stetclitakasdtest
noseatakimata noseatakimataatveroeosipsum
loremipsumdolor atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr consetetursadipscingelitr
MODIFICA #2
Se devi concatenare gli ID dalla tabella a_x
(colonna b
), non i CLOB stessi, quindi sostituire t1.a
con t1.b
(e, nel ORDER BY
clausola di XMLAGG
, non hai bisogno di alcun cast
, basta 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