带Rep substr函数的列表标签函数

问题描述 投票:1回答:1

原始数据。

Col1    Col2    Col3    Col4
Ajay    G1  B1  10.201.131.27
Ajay    G1  B2  10.201.131.27
Ajay    G1  B1  10.201.131.28
Ajay    G1  B2  10.201.131.28
Ajay    G1  B1  10.201.131.29
Ajay    G1  B2  10.201.131.29

使用Oracle 10g的预期输出。

Col1    Col2    Col3    Col4
Ajay    G1  B1,B2   10.201.131.27,10.201.131.28, 10.201.131.29

如果有人能够帮助我,将非常高兴。

查询我用了。

select * from (select 
Col1,
Col2,
substr(regexp_replace(','||(LISTAGG(( CASE WHEN T1.COl3 IS NULL OR TRIM( T1.COl3 ) ='' THEN NULL ELSE T1.COl3   END), ',') WITHIN GROUP (ORDER BY T1.COl1 )), '(,[^,]+)(\1)+', '\1'),2) as COl3 ,
substr(regexp_replace(','||(LISTAGG(( CASE WHEN T1.COl4 IS NULL OR TRIM( T1.COl4 ) ='' THEN NULL ELSE  T1.COl4   END), ',') WITHIN GROUP (ORDER BY T1.COl1 )), '(,[^,]+)(\1)+', '\1'),2) as COl4 ,
from T1
Group by 
Col1
)abc

我得到的OUTOPUT如下。

Col1    Col2    Col3    Col4
Ajay    G1  B1,B2   10.201.131.27
Ajay    G1  B1,B2   10.201.131.28
Ajay    G1  B1,B2   10.201.131.29

先谢谢你。

oracle plsql oracle10g listagg
1个回答
3
投票

为了消除重复的内容,从 LISTAGG 您可以在 Oracle 10row_number 函数来定义 重复的顺序.

在下一步,你将进入 LISTAGG 只发挥 第一 (row_number = 1),所有较高的重复数据都会被重置成 NULL 忽略的 LISTAGG.

这里的查询

with t2 as (
select 
COL1, COL2,
COL3,
row_number() over (partition by col1, col2, col3 order by null) as rn3,
COL4,
row_number() over (partition by col1, col2, col4 order by null) as rn4
from t)
select
  COL1, COL2,
  listagg(case when rn3 = 1 then COL3 end,',') within group (order by COL3) COL3,
  listagg(case when rn4 = 1 then COL4 end,',') within group (order by COL4) COL4
from t2
group by COL1, COL2

结果

COL1,   COL2, COL3, COL4
Ajay    G1  B1,B2   10.201.131.27,10.201.131.28,10.201.131.29

请注意 这种方法远远优于事后淘汰法。 REGEXP 对于非平凡的数据,你经常会遇到这样的情况。ORA-01489: result of string concatenation is too long 淘汰赛.

还需要注意的是,你可以升级到Oracle 19(可以认为从Oracle 10的点逾期),你可以使用的功能。LISTAGG (DISTINCT 而不需要消除重复。这个版本还可以优雅地处理 owerflow 的问题。


1
投票
with t (Col1,    Col2,    Col3,    Col4) as (
select 'Ajay',    'G1',  'B1',  '10.201.131.27' from dual union all
select 'Ajay',    'G1',  'B2',  '10.201.131.27' from dual union all
select 'Ajay',    'G1',  'B1',  '10.201.131.28' from dual union all
select 'Ajay',    'G1',  'B2',  '10.201.131.28' from dual union all
select 'Ajay',    'G1',  'B1',  '10.201.131.29' from dual union all
select 'Ajay',    'G1',  'B2',  '10.201.131.29' from dual)
, t1 as (
select Col1, Col2
, listagg(Col3, ',') within group (order by Col3) x
, listagg(Col4, ',') within group (order by Col4) y
from t
group by Col1, Col2
)
select Col1, Col2
, rtrim(regexp_replace(x || ',', '([^,]+,)\1+', '\1'), ',') Col3_
, rtrim(regexp_replace(y || ',', '([^,]+,)\1+', '\1'), ',') Col4_
from t1
;

COL1  CO  COL3_                           COL4_                                                       
----  --  ------------------------------  ------------------------------------------------------------
Ajay  G1  B1,B2                           10.201.131.27,10.201.131.28,10.201.131.29                     

我是分两步展示,但也可以一步到位。

select Col1, Col2
, rtrim(regexp_replace(listagg(Col3, ',') within group (order by Col3) || ',', '([^,]+,)\1+', '\1'), ',') Col3_
, rtrim(regexp_replace(listagg(Col4, ',') within group (order by Col4) || ',', '([^,]+,)\1+', '\1'), ',') Col4_
from t
group by Col1, Col2
;
© www.soinside.com 2019 - 2024. All rights reserved.