You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Oracle正则表达式LISTAGG去重失效(含中文场景)求助

解决LISTAGG聚合后中文字符重复项无法移除的问题

嘿,这个问题我太熟了!你用的正则之所以搞不定中文字符的重复项,本质是Oracle正则表达式的默认匹配逻辑在搞鬼——它默认按单字节字符来解析字符串,而中文字符(比如UTF-8编码下是3字节)会被拆成单个字节,[^,]+根本没法识别出完整的重复中文词。下面给你两种靠谱的解决办法,优先推荐第一种,简单又高效:

方法1:用DISTINCT直接在LISTAGG中去重(推荐)

如果你的Oracle版本是12cR2及以上,直接在LISTAGG里加DISTINCT就能一步到位,这是官方支持的最优方案,比正则替换性能好太多,还能避免正则的各种边缘问题:

LISTAGG(DISTINCT PR.NAME, ',') WITHIN GROUP (ORDER BY PR.NAME) AS PRODUCERS

注意:这里把ORDER BY 1改成了ORDER BY PR.NAME,让结果排序更明确,如果你不需要特定排序,也可以保留ORDER BY 1

方法2:修改正则表达式的匹配模式(兼容旧版本)

如果你的Oracle版本低于12cR2,没法用DISTINCT,那可以给REGEXP_REPLACE加一个'n'参数,让它按Unicode字符(多字节)模式匹配,这样就能正确识别完整的中文字符了:

REGEXP_REPLACE(
    LISTAGG(PR.NAME, ',') WITHIN GROUP (ORDER BY 1),
    '([^,]+)(,\1)+', '\1', 1, 0, 'n'
) AS PRODUCERS

这里的'n'参数是关键:它告诉Oracle把字符串当作Unicode字符序列处理,而不是拆分单字节,这样[^,]+就能准确匹配每一个完整的中文名称了。

额外提醒

如果你的PR.NAME字段里本身包含逗号,那不管用哪种方法都会出问题——LISTAGG的分隔符和字段内容冲突了。这种情况得先把字段里的逗号替换成其他字符(比如顿号),再进行聚合和去重。

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

火山引擎 最新活动