如何使用Oracle的LISTAGG功能和独特的过滤器?

dav*_*lab 48 oracle group-by aggregate-functions oracle11g

我有这样一张桌子:

group_id  name  
--------  ----
1         David
1         John
1         Alan
1         David
2         Julie
2         Charles
Run Code Online (Sandbox Code Playgroud)

我想要以下结果:

group_id  names
--------  -----
1         'Alan, David, John'
2         'Charles, Julie'
Run Code Online (Sandbox Code Playgroud)

我可以使用以下查询:

select group_id, 
       listagg(name, ',') within group (order by name) as names
from demotable
group by group_id 
Run Code Online (Sandbox Code Playgroud)

为了得到这个(非常相似的结果):

group_id  names
--------  -----
1         'Alan, David, David, John'
2         'Charles, Julie'
Run Code Online (Sandbox Code Playgroud)

我有什么想法可以通过LISTAGG呼叫中的唯一性过滤名称?

Oll*_*lie 48

我今天没有11g实例,但你不能使用:

SELECT group_id,
       LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names
  FROM (
       SELECT UNIQUE
              group_id,
              name
         FROM demotable
       )
 GROUP BY group_id
Run Code Online (Sandbox Code Playgroud)


ozm*_*ike 16

超级简单的答案 - 解决了!

select group_id, 
regexp_replace(
    listagg(name, ',') within group (order by name)
    ,'([^,]+)(,\1)*(,|$)', '\1\3')
from demotable
group by group_id;  
Run Code Online (Sandbox Code Playgroud)

这仅在您将分隔符指定为','而不是'时才有效,即仅在逗号后面没有空格.如果你想要逗号之后的空格 - 这是一个例子.

select 
replace(
    regexp_replace(
     regexp_replace('BBall, BBall, BBall, Football, Ice Hockey ',',\s*',',')            
    ,'([^,]+)(,\1)*(,|$)', '\1\3')
,',',', ') 
from dual
Run Code Online (Sandbox Code Playgroud)

给BBall,足球,冰上曲棍球

我的完整答案在这里


小智 5

create table demotable(group_id number, name varchar2(100));
insert into demotable values(1,'David');
insert into demotable values(1,'John');
insert into demotable values(1,'Alan');
insert into demotable values(1,'David');
insert into demotable values(2,'Julie');
insert into demotable values(2,'Charles');
commit;

select group_id, 
       (select listagg(column_value, ',') within group (order by column_value) from table(coll_names)) as names
from (
  select group_id, collect(distinct name) as coll_names 
    from demotable
    group by group_id 
)

GROUP_ID    NAMES
1   Alan,David,John
2   Charles,Julie
Run Code Online (Sandbox Code Playgroud)