You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle中这段正则去重SQL的\1符号及正则逻辑是什么含义?

SQL正则去重拼接逻辑详解

原SQL如下:

SELECT  REGEXP_REPLACE(LISTAGG(A.ID, ',') WITHIN GROUP (ORDER BY A.ID), '([^,]+)(,\1)+', '\1')
FROM    TABLE A

\1的具体含义

\1是正则语法里的反向引用,指代匹配过程中,正则模式里第1个被圆括号包裹的捕获组实际匹配到的文本内容。

完整实现逻辑

这是Oracle 19c版本(该版本首次原生支持LISTAGG(DISTINCT 列, 分隔符)的去重写法)之前,实现字段去重拼接的经典偏方,必须依赖WITHIN GROUP (ORDER BY A.ID)的排序规则才能正常工作,执行流程分两步:

  • 第一步执行LISTAGG聚合:将表A的所有ID按升序排列后,用逗号做分隔符拼接为单个长字符串。因为提前做了排序,取值相同的ID会连续挨在一起,举个实际例子,如果ID列取值是1111、1111、2222、3333、3333,拼接结果就是1111,1111,2222,3333,3333。
  • 第二步执行REGEXP_REPLACE正则替换,匹配模式为([^,]+)(,\1)+,各部分作用:
    • ([^,]+):第1个捕获组,匹配1个及以上连续的非逗号字符,刚好对应拼接串里的单个ID值——你用的A.ID是NUMBER(4)类型的纯数字,本身不含逗号,不会出现匹配错位的问题。
    • (,\1)+:匹配「英文逗号 + 第1个捕获组匹配到的完全一致的内容」,要求这个组合连续出现至少1次,本质就是匹配某个ID后面跟着的所有连续重复的,ID片段。
  • 替换规则是把匹配到的整段连续重复ID串,替换为单个\1也就是单个ID值,直接删掉所有多余的重复项。还是以上面的拼接串举例:
    • 连续重复段1111,1111会被替换为单个1111
    • 没有重复的2222不会被匹配替换
    • 连续重复段3333,3333会被替换为单个3333
      最终输出结果就是1111,2222,3333,达到去重拼接的目的。

生效前提

这个写法不是通用去重方案,必须满足LISTAGG内对拼接的ID字段做排序的要求,保证相同ID连续排列。如果去掉排序逻辑,相同ID可能被其他值隔开,比如拼接结果为1111,2222,1111,正则无法识别非连续的重复项,去重就会失效。

内容的提问来源于stack exchange,提问作者eastglow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:42:19