Sql 使用Oracle Listag函数消除重复项

Sql 使用Oracle Listag函数消除重复项,sql,oracle,plsql,analytics,oracle11gr2,Sql,Oracle,Plsql,Analytics,Oracle11gr2,可能重复: 我正在使用OracleListag函数,但在返回的名称列表中,我实际上希望消除重复项,只返回不同的值 我的问题是这样的: select a.id, a.change_id, LISTAGG(b.name, ',') WITHIN GROUP (ORDER BY b.name) AS "Product Name", from table_a a, table_b b where a.id = 1 and b.change_id

可能重复:

我正在使用OracleListag函数,但在返回的名称列表中,我实际上希望消除重复项,只返回不同的值

我的问题是这样的:

select a.id,
       a.change_id,
       LISTAGG(b.name, ',') WITHIN GROUP (ORDER BY b.name) AS "Product Name", 
from   table_a a,
       table_b b
where  a.id = 1
and    b.change_id = c.change_id
group by a.id, a.change_id
目前,它只显示了一条记录:

1    1   NameA, NameA, NameB, NameC, NameD, Name D
我想退回的是:

1    1   NameA, NameB, NameC, Name D

由于评论中的链接答案没有提供我的解决方案,我还是会发布它

我将仅使用带有虚拟数据的表_b来显示概念,您可以轻松添加连接等:

with table_b as ( -- dummy data
 select 'name'||mod(level,3) name
        ,mod(level,3) id
   from dual
  connect by level < 10
 union all
 select 'name'||mod(level,2) name
        ,mod(level,3) id
   from dual
  connect by level < 10
)
select id
      ,RTRIM (
              XMLAGG (
                      XMLELEMENT (E,XMLATTRIBUTES (name|| ',' AS "Seg")
                      )
                     ORDER BY name ASC
              ).EXTRACT ('./E[not(@Seg = preceding-sibling::E/@Seg)]/@Seg'),
              ','
             ) AS "Product Name"
       ,LISTAGG(b.name, ',') WITHIN GROUP (ORDER BY b.name) AS "Product Name with dups"
  from table_b b
group by id;

与简单的Listag解决方案相比,这个想法来自于

可能的重复,在这里也必须非常缓慢。。。然而,我喜欢它@卢卡塞德:是的,这可能会慢一些,但Listag没有DISTINCT,所有其他解决方案要么进行两次完整表扫描,要么使用regexp,这也比Listag慢。感谢您喜欢itI我不确定是否仅仅因为应用了DISTINCT而引入了全表扫描?使用LISTAGG或任何其他聚合方法列出组中的所有元素,无论如何都将不可避免地进行完整表扫描,列出的字段上缺少索引。。。我可以想象这是最有效的,但那只是一个例子guess@LukasEder当前位置正确,但我的意思不仅仅是清楚。我曾考虑过需要多列的subselect,但这个答案提供了一个很好的解决方案