【问题标题】:Remove duplicate values from comma separated string in Oracle从 Oracle 中的逗号分隔字符串中删除重复值
【发布时间】:2016-05-21 13:46:16
【问题描述】:

我需要您对 regexp_replace 函数的帮助。我有一个表,其中有一列用于连接字符串值,其中包含重复项。如何消除它们?

例子:

Ian,Beatty,Larry,Neesha,Beatty,Neesha,Ian,Neesha

我需要输出是

Ian,Beatty,Larry,Neesha

重复是随机的,没有任何特定的顺序。

更新--

这是我的桌子的样子

ID   Name1   Name2    Name3     
1     a       b         c
1     c       d         a
2     d       e         a
2     c       d          b

每个 ID 需要一行,在一行中具有不同的 name1、name2、name3 作为逗号分隔的字符串。

ID    Name
1     a,c,b,d,c
2     d,c,e,a,b

我尝试使用具有 distinct 的 listagg,但无法删除重复项。

【问题讨论】:

  • 使用正确的联结表——甚至是嵌套表——而不是逗号分隔的列表,这是多么好的理由。祝你好运。
  • 这看起来是this的骗子
  • 模式不同,不适用于我的数据。复制品仍然存在。

标签: sql oracle listagg


【解决方案1】:

那么,试试这个...

([^,]+),(?=.*[A-Za-z],[] ]*\1)

【讨论】:

    【解决方案2】:

    如果重复值不相邻,我认为您不能仅使用 regexp_replace 来做到这一点。一种方法是将值拆分,消除重复项,然后将它们重新组合在一起。

    标记分隔字符串的常用方法是使用regexp_substrconnect by 子句。在字符串中使用绑定变量可以使代码更清晰:

    var value varchar2(100);
    exec :value := 'Ian,Beatty,Larry,Neesha,Beatty,Neesha,Ian,Neesha';
    
    select regexp_substr(:value, '[^,]+', 1, level) as value
    from dual
    connect by regexp_substr(:value, '[^,]+', 1, level) is not null;
    
    VALUE                        
    ------------------------------
    Ian                           
    Beatty                        
    Larry                         
    Neesha                        
    Beatty                        
    Neesha                        
    Ian                           
    Neesha                        
    

    您可以将其用作子查询(或 CTE),从中获取不同的值,然后使用 listagg 重新组合它:

    select listagg(value, ',') within group (order by value) as value
    from (
      select distinct value from (
        select regexp_substr(:value, '[^,]+', 1, level) as value
        from dual
        connect by regexp_substr(:value, '[^,]+', 1, level) is not null
      )
    );
    
    VALUE                        
    ------------------------------
    Beatty,Ian,Larry,Neesha       
    

    如果您正在查看表中的多行,这会有点复杂,因为这会混淆 connect-by 语法,但您可以使用非确定性引用来避免循环:

    with t42 (id, value) as (
      select 1, 'Ian,Beatty,Larry,Neesha,Beatty,Neesha,Ian,Neesha' from dual
      union all select 2, 'Mary,Joe,Mary,Frank,Joe' from dual
    )
    select id, listagg(value, ',') within group (order by value) as value
    from (
      select distinct id, value from (
        select id, regexp_substr(value, '[^,]+', 1, level) as value
        from t42
        connect by regexp_substr(value, '[^,]+', 1, level) is not null
        and id = prior id
        and prior dbms_random.value is not null
      )
    )
    group by id;
    
            ID VALUE                        
    ---------- ------------------------------
             1 Beatty,Ian,Larry,Neesha       
             2 Frank,Joe,Mary                
    

    当然,如果您正确存储关系数据,则没有必要这样做;在列中使用分隔字符串不是一个好主意。

    【讨论】:

    • 我会试试这个并让你知道......数据实际上并不以分隔字符串的形式存在。它来自每个 id 的多行,我使用 listagg 将它们连接成每个 id 的 1 行
    • @Cindy - 那么为什么你不只是在调用 listagg 之前获取不同的值呢?
    猜你喜欢
    • 1970-01-01
    • 2018-08-27
    • 2012-01-30
    • 2021-11-08
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多