Oracle listagg去重distinct三種方法總結


 

首先還原listagg聚合之后出現重復數據的現象,打開plsql,執行如下sql:

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

運行結果:

如圖,listagg聚合之后很多重復數據,下面講解如何解決重復數據問題。

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

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

如上圖,listagg聚合之后沒有出現重復數據了。oracle官方不太推薦使用wm_concat()來進行聚合,能盡量使用listagg就使用listagg。

【b】第二種方法:使用正則替換方式去重(僅適用於oracle字符串大小比較小的情況)

1 --第二種方法:使用正則替換方式去重(僅適用於oracle字符串大小比較小的情況)
2 select t.department_name depname,
3        t.department_key,
4        regexp_replace(listagg(t.class_key, ',') within
5                       group(order by t.class_key),
6                       '([^,]+)(,\1)*(,|$)',
7                       '\1\3') as class_keys
8   from V_YDXG_TEACHER_KNSRDGL t
9  group by t.department_key, t.department_name;

這種方式處理listagg去重問題如果拼接的字符串太長會報oracle超過最大長度的錯誤,只適用於數據量比較小的場景。

【c】第三種方法:先去重,再聚合(推薦使用)

 1 --第三種方法:先去重,再聚合
 2 select t.department_name depname,
 3        t.department_key,
 4        listagg(t.class_key, ',') within group(order by t.class_key) as class_keys
 5   from (select distinct s.class_key, s.department_key, s.department_name
 6           from V_YDXG_TEACHER_KNSRDGL s) t
 7  group by t.department_key, t.department_name
 8  
 9 --或者
10 select s.department_key,
11        s.department_name,
12        listagg(s.class_key, ',') within group(order by s.class_key) as class_keys
13   from (select t.department_key,
14                t.department_name,
15                t.class_key,
16                row_number() over(partition by t.department_key, t.department_name, t.class_key order by t.department_key, t.department_name) as rn
17           from V_YDXG_TEACHER_KNSRDGL t
18          order by t.department_key, t.department_name, t.class_key) s
19  where rn = 1
20  group by s.department_key, s.department_name;
21  

推薦使用這種方式,先把重復數據去重之后再進行聚合處理。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM