Oracle listagg去重distinct三种方法总结

1、简介

最近在工做中,在写oracle统计查询的时候,遇到listagg聚合函数分组聚合以后出现不少重复数据的问题,因而研究了一下listagg去重的几种方法,如下经过实例讲解三种实现listagg去重的方法。sql

2、方法

首先还原listagg聚合以后出现重复数据的现象,打开plsql,执行以下sql:oracle

select t.department_name depname,
       t.department_key,
       listagg(t.class_key, ',') within group(order by t.class_key) as class_keys
  from V_YDXG_TEACHER_KNSRDGL t
 where 1 = 1
 group by t.department_key, t.department_name

运行结果:函数

如图,listagg聚合以后不少重复数据,下面讲解如何解决重复数据问题。学习

【a】 第一种方法: 使用wm_concat() + distinct去重聚合3d

--第一种方法: 使用wm_concat() + distinct去重聚合
select t.department_name depname,
       t.department_key,
       wm_concat(distinct t.class_key) as class_keys
  from V_YDXG_TEACHER_KNSRDGL t
 where 1 = 1
 group by t.department_key, t.department_name

如上图,listagg聚合以后没有出现重复数据了。oracle官方不太推荐使用wm_concat()来进行聚合,能尽可能使用listagg就使用listagg。code

 

【b】第二种方法:使用正则替换方式去重(仅适用于oracle字符串大小比较小的状况)regexp

--第二种方法:使用正则替换方式去重(仅适用于oracle字符串大小比较小的状况)
select t.department_name depname,
       t.department_key,
       regexp_replace(listagg(t.class_key, ',') within
                      group(order by t.class_key),
                      '([^,]+)(,\1)*(,|$)',
                      '\1\3') as class_keys
  from V_YDXG_TEACHER_KNSRDGL t
 group by t.department_key, t.department_name;

这种方式处理listagg去重问题若是拼接的字符串太长会报oracle超过最大长度的错误,只适用于数据量比较小的场景。blog

 

【c】第三种方法:先去重,再聚合(推荐使用)字符串

--第三种方法:先去重,再聚合
select t.department_name depname,
       t.department_key,
       listagg(t.class_key, ',') within group(order by t.class_key) as class_keys
  from (select distinct s.class_key, s.department_key, s.department_name
          from V_YDXG_TEACHER_KNSRDGL s) t
 group by t.department_key, t.department_name

--或者
select s.department_key,
       s.department_name,
       listagg(s.class_key, ',') within group(order by s.class_key) as class_keys
  from (select t.department_key,
               t.department_name,
               t.class_key,
               row_number() over(partition by t.department_key, t.department_name, t.class_key order by t.department_key, t.department_name) as rn
          from V_YDXG_TEACHER_KNSRDGL t
         order by t.department_key, t.department_name, t.class_key) s
 where rn = 1
 group by s.department_key, s.department_name;

推荐使用这种方式,先把重复数据去重以后再进行聚合处理。it

3、总结

以上就是关于listagg聚合函数去重的三种处理方法的总结,本文仅仅是笔者的一些总结和看法,仅供你们学习参考,但愿能对你们有所帮助。