子查询错误或使用xmllagg的值过多

时间:2019-02-13 09:04:34

标签: sql oracle

我在连接来自许多大型表的所有数据时遇到问题。我昨天问了这个问题,但是不幸的是listagg并不是一个好选择。链接subquery return more than one row

在我的oracle 12.0.1版本中,我无法使用listagg来截断listagg之后使用xmllagg,如下所示的第一个代码是给子查询返回了多行...

SELECT rtrim(xmlagg(XMLELEMENT(e,table1.DESCRIPTION,',').EXTRACT  ('//text()')
              ).GetClobVal(),',') 
    FROM table1

 left  join table2 on  table1.app = table2.app
 AND LANGUAGE = 2
   GROUP BY table2.app

使用另一种方法的第二个代码仍然在第一行中说出太多的值

     SELECT nvl(max(case when language = 2 then description end), 'NULL')      key_event,     rtrim(xmlagg(XMLELEMENT              (e,table1.DESCRIPTION,',').EXTRACT  ('//text()')
              ).GetClobVal(),',') 
    FROM table1

 left  join table2 on  table1.app = table2.app
 AND LANGUAGE = 2
   GROUP BY table2.app 

我已经在此链接dbfiddle中测试了这2个代码,并且可以正常工作。我希望结果是此链接

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=40852eaeaa8f334f77364eef77ffbe68

enter image description here

我确实得到了对其进行少量测试的结果,但是当我尝试使用完整代码时,只看这段代码,它就无法正常工作,请查看代码和错误下面的错误error:subquery返回多行

              SELECT  
        NVL(TO_CHAR(D_TRANS.TRANS), 'NULL') AS ID, 
        'HEADER'

  , (SELECT L_APPLICATION.APPLICATION FROM L_APPLICATION   L_APPLICATION WHERE LANGUAGE = 2 AND APPLICATION = D_TRANS.APPLICATION) AS   CASE_TYPE
  , NVL(TO_CHAR(D_TRANS.UNIT_IN_CHARGE), 'NULL') AS UNIT_IN_CHARGE
  , NVL(TO_CHAR(D_TRANS.PERSON_IN_CHARGE), 'NULL') AS PERSON_IN_CHARGE
  , NVL(TO_CHAR(D_TRANS.STATUS), 'NULL') AS CASE_STATUS
   , NVL(TO_CHAR(D_TRANS.DEADLINE), 'NULL') AS INTERNAL_DEADLINE





            (SELECT  D_SYNERGI_CATEGORY.TRANS, nvl(max(case when language =    2 then description end), 'NULL') AS ADE ,  rtrim(xmlagg(XMLELEMENT   (e,L_CASE_CATEGORY.DESCRIPTION,',').EXTRACT('//text()')
  ).GetClobVal(),',') 
             FROM L_CASE_CATEGORY

        left join   D_SYNERGI_CATEGORY  on         D_SYNERGI_CATEGORY.CASE_CATEGORY =  L_CASE_CATEGORY.CASE_CATEGORY   

         GROUP BY  D_SYNERGI_CATEGORY.TRANS

                            ) 


                 )


                 FROM D_TRANS
                        FULL OUTER  JOIN D_SPILL
                     ON D_TRANS.TRANS=D_SPILL.TRANS


                    ORDER BY D_TRANS.TRANS DESC;

当我测试下面这段代码的这一小部分时,它正在工作。

                         (SELECT  D_SYNERGI_CATEGORY.TRANS, nvl(max(case    when language = 2 then description end), 'NULL') AS ADE ,  rtrim(xmlagg(XMLELEMENT(e,L_CASE_CATEGORY.DESCRIPTION,',').EXTRACT('//text()')
  ).GetClobVal(),',') 
      FROM L_CASE_CATEGORY

       left join   D_SYNERGI_CATEGORY  on  D_SYNERGI_CATEGORY.CASE_CATEGORY     =  L_CASE_CATEGORY.CASE_CATEGORY   

        GROUP BY  D_SYNERGI_CATEGORY.TRANS

                        ) 

我不是Oracle专家。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

使用REGEXP_REPLACE,我们可以进行重复数据删除。检查一下:

select  t2.app,  
       coalesce(max(case when language =  2 then description end), 
                max(case when language = 12 then description end), 
                max(case when language = 27 then description end), 
               'NULL') key_event,
        REGEXP_REPLACE(listagg(description, ',') within group (order by t1.description, t1.language), '([^,]+)(,\1)+', '\1') list
  from table2 t2 
  left join table1 t1 on t1.app = t2.app 
  group by trans, t2.app
  order by trans, trans;

答案 1 :(得分:0)

xmlagg和xQuery的组合,这并不简单。

select xmlquery('distinct-values(//text())' passing x returning content).getclobVal(),data_type from (
    select   xmlelement(root, xmlagg(XMLELEMENT(e,table_name,','))) x ,data_type
     from user_tab_cols where data_type in ('VARCHAR2','NUMBER')     
     group by data_type
     )

出于您的目的,它应该看起来像这样

select 
    app, key_event,  
    xmlquery('distinct-values(//text())' passing xmldoc returning content).getclobVal()
from 
    (select  
         t2.app,  
         coalesce(max(case when language =  2 then description end), 
                  max(case when language = 12 then description end), 
                  max(case when language = 27 then description end), 
                  'NULL') key_event,
         XMLELEMENT(root, xmlagg(XMLELEMENT(e, description, ','))
    ) xmldoc
from 
    table2 t2 
left join 
    table1 t1 on t1.app = t2.app 
group by 
    trans, t2.app
order by trans);

如果要分解此查询,您将了解其工作原理。

xquery distinct-values syntax

xmlquery syntax