查询中的Sum Listagg

时间:2016-03-07 07:44:27

标签: oracle sum listagg

我正在尝试对我所做的listagg查询中的值求和。

预期结果应该是这样的

SELECT LEGAL_ENTITY_ID, SUM(0 + 0 + 0 + 1) as Grandtotals
FROM V_VBA_DDCR_MAIN WHERE LEGAL_ENTITY_ID=6012346 AND ROWNUM=1
GROUP BY LEGAL_ENTITY_ID

 |      LEGAL_ENTITY_ID | GRANDTOTALS 
1|    6012346           | 1

我的listagg就像这样

SELECT LISTAGG(NVL2(FLDNM,0,1) , '+ ') WITHIN GROUP (ORDER BY FLDNM) FROM LE_MERGE_DDC_MAPPING

此查询的目的是计算一行中的空字段数。我创建了一个表,其中包含需要检查空值的字段列表。

结果:

    fld1 + fld2 + fld3 + fld4
=
        0 + 0 + 0 + 1

所以我写了这样的查询:

SELECT LEGAL_ENTITY_ID, SUM(SELECT LISTAGG(NVL2(FLDNM,0,1) , '+ ') WITHIN GROUP 
(ORDER BY FLDNM) FROM LE_MERGE_DDC_MAPPING) as Grandtotals
FROM V_VBA_DDCR_MAIN WHERE LEGAL_ENTITY_ID=6000132
GROUP BY LEGAL_ENTITY_ID

但是,我收到错误ORA-00936:表达式丢失。 我不确定Oracle是否允许您对listagg函数进行总结。 任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

除非SELECT LISTAGG(NVL2(FLDNM,0,1) , '+ ')...中的行为空,否则'0+ 0+ 0+ ...'查询将始终获得字符串结果LE_MERGE_DDC_MAPPING。该值与V_VBA_DDCR_MAIN表无关。您可以生成包含表达式的字符串:

SELECT LISTAGG('NVL2(' || FLDNM || ' ,0,1)' , '+ ') ...

但是这只会让你留下一个包含'NVL2(fld1 ,0,1)+ NVL2(fld2 ,0,1)+ ...'字符串。您不能对字符串求和,sum()无法将字符串作为表达式求值。您需要基于该字符串生成动态SQL语句。

有一种方法可以用XML做到这一点,这并不完全直观。您可以使用dbms_xmlgen包创建XML文档(作为CLOB),其中包含具有来自实际目标表的NVL2结果的节点:

select dbms_xmlgen.getxml('select nvl2(' || fldnm || ',0,1) from v_vba_ddcr_main where legal_entity_id=6012346')
from le_merge_ddc_mapping map;

我不会在这里显示生成的XML。然后,您可以查询以获取单个值:

select xmlquery('/ROWSET/ROW/*/text()'
  passing xmltype(
    dbms_xmlgen.getxml('select nvl2(' || fldnm || ',0,1) from v_vba_ddcr_main where Legal_Entity_Id=6012346')
  ) 
  returning content)
from le_merge_ddc_mapping;

你可以将它们总结为:

select sum(to_number(xmlquery('/ROWSET/ROW/*/text()'
  passing xmltype(
    dbms_xmlgen.getxml('select nvl2(' || fldnm || ',0,1) from v_vba_ddcr_main where legal_entity_id=6012346')
  )
  returning content))) as grandtotals
from le_merge_ddc_mapping;

您已建议表之间存在链接,以确定包含哪些字段,因此您需要添加该字段。并且你已经说过你需要处理的重复项 - 最好是从你的视图中删除它们,但必要时使用子查询。这可以作为你从中发展的起点。

答案 1 :(得分:0)

为什么要使用LISTAGG

SELECT LEGAL_ENTITY_ID,
       (
         SELECT COUNT(1)
         FROM   LE_MERGE_DDC_MAPPING
         WHERE  FLDNM IS NULL
       ) as Grandtotals
FROM   V_VBA_DDCR_MAIN
WHERE  LEGAL_ENTITY_ID=6000132;

(由于您要对单个LEGAL_ENTITY_ID进行过滤,因此不需要最终GROUP BY

你确定两个表之间不应该存在某种连接条件吗?