带有 rep substr 函数的 Listagg 函数
Listagg function with rep substr function
原始数据:
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 )), '(,[^,]+)()+', ''),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 )), '(,[^,]+)()+', ''),2) as COl4 ,
from T1
Group by
Col1
)abc
我得到的输出如下,
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
提前致谢。
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 || ',', '([^,]+,)+', ''), ',') Col3_
, rtrim(regexp_replace(y || ',', '([^,]+,)+', ''), ',') 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) || ',', '([^,]+,)+', ''), ',') Col3_
, rtrim(regexp_replace(listagg(Col4, ',') within group (order by Col4) || ',', '([^,]+,)+', ''), ',') Col4_
from t
group by Col1, Col2
;
要消除 LISTAGG
中的重复,您可以在 Oracle 10
中使用 row_number
函数来定义 重复的顺序 。
在下一步中,您只传递给 LISTAGG
函数 first duplicated (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
问题。
原始数据:
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 )), '(,[^,]+)()+', ''),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 )), '(,[^,]+)()+', ''),2) as COl4 ,
from T1
Group by
Col1
)abc
我得到的输出如下,
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
提前致谢。
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 || ',', '([^,]+,)+', ''), ',') Col3_
, rtrim(regexp_replace(y || ',', '([^,]+,)+', ''), ',') 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) || ',', '([^,]+,)+', ''), ',') Col3_
, rtrim(regexp_replace(listagg(Col4, ',') within group (order by Col4) || ',', '([^,]+,)+', ''), ',') Col4_
from t
group by Col1, Col2
;
要消除 LISTAGG
中的重复,您可以在 Oracle 10
中使用 row_number
函数来定义 重复的顺序 。
在下一步中,您只传递给 LISTAGG
函数 first duplicated (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
问题。