Oracle
 sql >> Base de données >  >> RDS >> Oracle

Mot clé FROM introuvable là où il était attendu, sélection de texte Oracle SQL

L'erreur immédiate est causée par deux alias donnés au résultat de la concaténation :vous avez AS LIST as ids . Vous ne pouvez pas donner deux alias au résultat d'un calcul. Si vous voulez que la table nouvellement créée ait une colonne LIST puis supprimez as ids , et vice versa.

Ensuite, vous rencontrerez une autre erreur :vous essayez de ORDER BY t1.a dans l'agrégation. Cela ne fonctionnera pas; vous ne pouvez pas trier par un CLOB dans l'agrégation XML. Vous souciez-vous vraiment de l'ordre dans lequel l'agrégation se produit ? Si vous ne le faites pas, changez pour ORDER BY NULL . Si vous vous en souciez, vous avez un problème, car dans Oracle une order_by_clause ne peut tout simplement pas ordonner par une expression CLOB. Vous devrez créer une colonne distincte pour commander en utilisant d'autres méthodes.

Dans la solution globale, la clause WITH n'est pas nécessaire. Partout où vous faites référence à "input_strings" dans la requête (autre que la clause WITH), écrivez simplement "table_expressions".

MODIFIER

Voici comment cela pourrait être fait pour fonctionner. Je vais d'abord montrer les instructions CREATE TABLE. Je suppose que table_expressions a une colonne CLOB de chaînes de recherche et qu'il n'y a AUCUN DUPLICAT dans cette colonne. Même ainsi, la table a également besoin d'une clé primaire distincte, d'un type de données qui n'est pas LOB ou d'un autre type long non standard. J'utilise NUMBER pour cela.

Ensuite, j'agrège par cette colonne de clé primaire. Hélas, je ne peux pas sélectionner la chaîne de recherche en même temps. Je pourrais SELECT MAX(t2.a) mais cela ne fonctionne pas non plus avec les valeurs CLOB ! Au lieu de cela, j'ai besoin d'une autre jointure pour faire correspondre la clé primaire à la chaîne de recherche. (Désolé, la requête prendra beaucoup plus de temps à cause de cela...)

Dans l'agrégation, je trie par les 4000 premiers caractères de la valeur de chaîne de la colonne a . Ce n'est pas aussi bon que de trier par la chaîne d'entrée entière, mais c'est toujours mieux que de trier par 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
;

Vérifions maintenant ce que nous avons :

select * from a_y;

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

MODIFICATION #2

Si vous avez besoin de concaténer les identifiants de la table a_x (colonne b ), pas les CLOB eux-mêmes, alors remplacez t1.a avec t1.b (et, dans le ORDER BY clause de XMLAGG , vous n'avez pas besoin de cast , juste 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