Oracle SQL:如何删除 listagg 中的重复项
Oracle SQL: How to remove duplicate in listagg
使用 listagg 合并我的数据后,有很多重复项需要删除。
Original Table
我的数据中总共只有3种技术,没有特定的模式。我想知道是否可以删除所有重复项并只在相应行中保留一种类型?
select
NAME,
RTRIM(
REGEXP_REPLACE(
(LISTAGG(
NVL2(Membrane_column, 'Membrane, ', NULL)
|| NVL2(SNR_column, 'SNR, ', NULL)
|| NVL2(SMR_column, 'SMR, ', NULL)
) within group (ORDER BY name)),
'Membrane, |SNR, |SMR, ', '', '1', '1', 'c')
', ')
as TECHNOLOGY
from
Table A
目前table我目前
Name
Technology
A
SNR, SMR, SMR, SNR
B
Membrane, SNR, SMR, Membrane
C
SMR, SMR, Membrane
想要Table
Name
Technology
A
SNR, SMR
B
Membrane, SNR, SMR
C
SMR, Membrane
这可能是一个简单的方法:
select name, listagg(technology, ', ') within group (order by 1) -- or whatever order you need
from
(
select distinct name, technology
from tableA
)
group by name
从 Oracle 19c 开始 listagg
支持 distinct
关键字。 within group
也成为可选项。
with a as (
select column_value as a
from table(sys.odcivarchar2list('A', 'B', 'A', 'B', 'C')) q
)
select listagg(distinct a, ',')
from a
LISTAGG(DISTINCTA,',')
----------------------
A,B,C
livesql 示例 here.
也许只需创建 SNR/SMR/Membrane 列的 SUM,按名称对它们进行分组,然后将数字替换为您希望在输出中看到的字符串。
查询(第一步...)
select name
, sum( snr_column ), sum( smr_column ), sum( membrane_column )
from original
group by name
;
-- output
NAME SUM(SNR_COLUMN) SUM(SMR_COLUMN) SUM(MEMBRANE_COLUMN)
2 1 1 2
3 null 2 1
1 2 2 null
用 RTRIM()
替换总和、连接、删除尾随逗号
select
name
, rtrim(
case when sum( snr_column ) >= 1 then 'SNR, ' end
|| case when sum( smr_column ) >= 1 then 'SMR, ' end
|| case when sum( membrane_column ) >= 1 then 'Membrane' end
, ' ,'
) as technology
from original
group by name
order by name
;
-- output
NAME TECHNOLOGY
1 SNR, SMR
2 SNR, SMR, Membrane
3 SMR, Membrane
按要求的顺序对 CASE 进行编码。
DBfiddle
使用 listagg 合并我的数据后,有很多重复项需要删除。
Original Table
我的数据中总共只有3种技术,没有特定的模式。我想知道是否可以删除所有重复项并只在相应行中保留一种类型?
select
NAME,
RTRIM(
REGEXP_REPLACE(
(LISTAGG(
NVL2(Membrane_column, 'Membrane, ', NULL)
|| NVL2(SNR_column, 'SNR, ', NULL)
|| NVL2(SMR_column, 'SMR, ', NULL)
) within group (ORDER BY name)),
'Membrane, |SNR, |SMR, ', '', '1', '1', 'c')
', ')
as TECHNOLOGY
from
Table A
目前table我目前
Name | Technology |
---|---|
A | SNR, SMR, SMR, SNR |
B | Membrane, SNR, SMR, Membrane |
C | SMR, SMR, Membrane |
想要Table
Name | Technology |
---|---|
A | SNR, SMR |
B | Membrane, SNR, SMR |
C | SMR, Membrane |
这可能是一个简单的方法:
select name, listagg(technology, ', ') within group (order by 1) -- or whatever order you need
from
(
select distinct name, technology
from tableA
)
group by name
从 Oracle 19c 开始 listagg
支持 distinct
关键字。 within group
也成为可选项。
with a as (
select column_value as a
from table(sys.odcivarchar2list('A', 'B', 'A', 'B', 'C')) q
)
select listagg(distinct a, ',')
from a
LISTAGG(DISTINCTA,',')
----------------------
A,B,C
livesql 示例 here.
也许只需创建 SNR/SMR/Membrane 列的 SUM,按名称对它们进行分组,然后将数字替换为您希望在输出中看到的字符串。
查询(第一步...)
select name
, sum( snr_column ), sum( smr_column ), sum( membrane_column )
from original
group by name
;
-- output
NAME SUM(SNR_COLUMN) SUM(SMR_COLUMN) SUM(MEMBRANE_COLUMN)
2 1 1 2
3 null 2 1
1 2 2 null
用 RTRIM()
替换总和、连接、删除尾随逗号select
name
, rtrim(
case when sum( snr_column ) >= 1 then 'SNR, ' end
|| case when sum( smr_column ) >= 1 then 'SMR, ' end
|| case when sum( membrane_column ) >= 1 then 'Membrane' end
, ' ,'
) as technology
from original
group by name
order by name
;
-- output
NAME TECHNOLOGY
1 SNR, SMR
2 SNR, SMR, Membrane
3 SMR, Membrane
按要求的顺序对 CASE 进行编码。 DBfiddle