Oracle SQL:如何删除 listagg 中的重复项

Posted

技术标签:

【中文标题】Oracle SQL:如何删除 listagg 中的重复项【英文标题】:Oracle SQL: How to remove duplicate in listagg 【发布时间】:2021-11-08 11:23:15 【问题描述】:

使用 listagg 合并我的数据后,我想删除许多重复项。

Original Table

我的数据中总共只有 3 种技术,没有特定的模式。我想知道是否可以删除所有重复项并在相应行中仅保留 1 种类型?


    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

我现在拥有的当前表

Name Technology
A SNR, SMR, SMR, SNR
B Membrane, SNR, SMR, Membrane
C SMR, SMR, Membrane

想要的表

Name Technology
A SNR, SMR
B Membrane, SNR, SMR
C SMR, Membrane

【问题讨论】:

想要的输出是什么? 完成。很抱歉不清楚前哨。 请将您的源数据发布为文本,而不是图像。 Why not upload images of code/errors when asking a question? idk 为什么我在发布表格时总是出错。这就是我发布图片的原因 请将其发布为纯文本或任何可以复制的内容,有人会编辑它。图片一点用都没有(手动输入所有数据真的很无聊)。 【参考方案1】:

这可能是一个简单的方法:

select name, listagg(technology, ', ') within group (order by 1) -- or whatever order you need
from 
(
  select distinct name, technology
  from tableA
)
group by name

【讨论】:

谢谢。但不是我想要的。在原始帖子中添加了所需的输出!【参考方案2】:

也许只需创建 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

【讨论】:

你拯救了我的一天!这行得通!哈哈。太感谢了。想知道 regexp_replace 几天来是如何工作的,而实际上有一个非常简单的解决方案! :)【参考方案3】:

从 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.

【讨论】:

谢谢。但不是我想要的。在原始帖子中添加了所需的输出! 如果您使用的是 Oracle 19c,这个答案就是您要找的。但这是关键,它只适用于 19c 起

以上是关于Oracle SQL:如何删除 listagg 中的重复项的主要内容,如果未能解决你的问题,请参考以下文章

oracle sql listagg [重复]

sql 从字符串..with毫秒的Oracle日期时间戳格式化。该示例还使用listagg在oracle中具有行的聚合

Oracle Database 19c 中的 LISTAGG DISTINCT

SQL 中的 STUFF 等效函数(MySQL 中的 GROUP_CONCAT / Oracle 中的 LISTAGG)

oracle WMSYS.WM_CONCAT 函数转为listagg

oracle listagg 拼接的字符串给多少长度