我在连接来自许多大型表的所有数据时遇到问题。我昨天问了这个问题,但是不幸的是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
我确实得到了对其进行少量测试的结果,但是当我尝试使用完整代码时,只看这段代码,它就无法正常工作,请查看代码和错误下面的错误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专家。有什么建议吗?
答案 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);
如果要分解此查询,您将了解其工作原理。