Oracle
 sql >> Datenbank >  >> RDS >> Oracle

FROM-Schlüsselwort nicht an der erwarteten Stelle gefunden, Textauswahl Oracle SQL

Der unmittelbare Fehler wird dadurch verursacht, dass dem Ergebnis der Verkettung zwei Aliase gegeben wurden:You have AS LIST as ids . Sie können dem Ergebnis einer Berechnung nicht zwei Aliase geben. Wenn Sie möchten, dass die neu erstellte Tabelle eine Spalte LIST hat dann as ids löschen , und umgekehrt.

Dann werden Sie auf einen weiteren Fehler stoßen:Sie versuchen ORDER BY t1.a in der Aggregation. Das wird nicht funktionieren; Sie können nicht nach einem CLOB in der XML-Aggregation bestellen. Ist es Ihnen wirklich wichtig, in welcher Reihenfolge die Aggregation erfolgt? Wenn nicht, wechseln Sie zu ORDER BY NULL . Wenn Sie sich darum kümmern, haben Sie ein Problem, da in Oracle eine order_by_clause kann einfach nicht nach einem CLOB-Ausdruck sortiert werden. Für die Bestellung mit anderen Methoden müssen Sie eine separate Spalte erstellen.

In der Gesamtlösung ist die WITH-Klausel nicht erforderlich. Überall dort, wo Sie in der Abfrage auf „input_strings“ verweisen (mit Ausnahme der WITH-Klausel), schreiben Sie einfach „table_expressions“.

BEARBEITEN

Hier ist, wie dies zum Laufen gebracht werden könnte. Zuerst zeige ich die CREATE TABLE-Anweisungen. Ich gehe davon aus, dass table_expressions eine CLOB-Spalte mit Suchzeichenfolgen hat und dass es KEINE DUPLIKATEN in dieser Spalte gibt. Trotzdem benötigt die Tabelle auch einen separaten Primärschlüssel eines Datentyps, der nicht LOB oder ein anderer langer, nicht standardmäßiger Typ ist. Ich verwende dafür NUMBER.

Dann aggregiere ich nach dieser Primärschlüsselspalte. Leider kann ich die Suchzeichenfolge nicht gleichzeitig auswählen. Ich könnte SELECT MAX(t2.a) aber das geht auch nicht mit CLOB-Werten! Stattdessen benötige ich einen weiteren Join, um den Primärschlüssel mit der Suchzeichenfolge abzugleichen. (Entschuldigung, die Abfrage dauert dadurch etwas länger...)

Bei der Aggregation sortiere ich nach den ersten 4000 Zeichen des Stringwerts aus Spalte a . Dies ist nicht so gut wie das Sortieren nach der gesamten Eingabezeichenfolge, aber immer noch besser als das Sortieren nach 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
;

Sehen wir uns nun an, was wir bekommen haben:

select * from a_y;

A                          IDS
-------------------------  ---------------------------------------------------------
atveroeosipsum             atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test                       stetclitakasdtest
stetclitakasd              stetclitakasdtest
noseatakimata              noseatakimataatveroeosipsum
loremipsumdolor            atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr  consetetursadipscingelitr

BEARBEITEN Nr. 2

Wenn Sie die IDs aus Tabelle a_x verketten müssen (Spalte b ), nicht die CLOBs selbst, dann ersetzen Sie t1.a mit t1.b (und im Feld ORDER BY Klausel von XMLAGG , brauchen Sie keinen cast , einfach 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