求Oracle查询语句:去除TITLE字段值内的重复内容
Oracle查询去除TITLE字段中重复的逗号分隔值
这里有两种实用的方法来实现你要的功能,分别适配不同的Oracle版本和场景:
方法一:拆分聚合(推荐,处理所有重复场景)
这个方法是最稳妥的,不管重复值是连续还是分散在字符串里,都能完美处理。核心思路是先把逗号分隔的字符串拆成独立行,去重后再重新拼接。
适用于Oracle 12c及以上版本
Oracle 12c开始支持在LISTAGG里直接用DISTINCT,代码更简洁:
SELECT film_id, LISTAGG(DISTINCT title_part, ',') WITHIN GROUP (ORDER BY title_part) AS title FROM your_table CROSS JOIN XMLTABLE( 'tokenize(., ",")' PASSING your_table.title COLUMNS title_part VARCHAR2(100) PATH '.' ) GROUP BY film_id;
适用于Oracle 11g及以下版本
如果你的版本不支持LISTAGG+DISTINCT,可以先在子查询里去重再聚合:
SELECT film_id, LISTAGG(title_part, ',') WITHIN GROUP (ORDER BY title_part) AS title FROM ( SELECT DISTINCT film_id, title_part FROM your_table CROSS JOIN XMLTABLE( 'tokenize(., ",")' PASSING your_table.title COLUMNS title_part VARCHAR2(100) PATH '.' ) ) GROUP BY film_id;
步骤解释:
XMLTABLE配合tokenize函数,把每个TITLE字段按逗号拆分成单独的行,每个行对应一个片段;- 通过
DISTINCT去掉同一个FILM_ID下重复的片段; - 最后用
LISTAGG把去重后的片段重新用逗号拼接成完整的字符串。
方法二:正则表达式替换(仅处理连续重复值)
如果你的场景里只有连续的重复值(比如Frozen,Frozen或High,High),可以用正则快速处理,但这种方法没法处理非连续的重复(比如Frozen,High,Frozen):
SELECT film_id, REGEXP_REPLACE(title, '([^,]+)(,\1)+', '\1') AS title FROM your_table;
正则逻辑说明:
([^,]+):匹配一个完整的、不含逗号的标题片段;(,\1)+:匹配后面跟着的「逗号+刚才匹配到的片段」的组合,至少出现一次;\1:把整个重复的部分替换成第一次匹配到的那个片段,从而去掉连续重复。
内容的提问来源于stack exchange,提问作者Cmsd
相关产品推荐
相关产品推荐

