oracle中的regexp_replace结合listagg组合后去重

1、首先准备数据表和数据:

CREATE V_TEST
   (	GROUP_CODE VARCHAR2(20 CHAR), 
	PRODUCT_ID VARCHAR2(200 CHAR)
   )

数据:

INSERT INTO V_TEST(GROUP_CODE,PRODUCT_ID) VALUES ('2405','111111111111111');
INSERT INTO V_TEST(GROUP_CODE,PRODUCT_ID) VALUES ('2711','111111111111111');
INSERT INTO V_TEST(GROUP_CODE,PRODUCT_ID) VALUES ('2712','111111111111111');
INSERT INTO V_TEST(GROUP_CODE,PRODUCT_ID) VALUES ('2718','111111111111111');
INSERT INTO V_TEST(GROUP_CODE,PRODUCT_ID) VALUES ('2711','111111111111111');
INSERT INTO V_TEST(GROUP_CODE,PRODUCT_ID) VALUES ('2718','111111111111111');
COMMIT;

2、执行如下查询:

select regexp_replace((listagg(T.GROUP_CODE, ',') within group(order by T.PRODUCT_ID)),  '(,[[:digit:]]+)(\1)+','\1') GROUP_CODE from V_TEST t GROUP BY T.PRODUCT_ID

执行结果如下图所示:
在这里插入图片描述
3、以上的语句只能对数字去重,那么通过以下语句可以对任何以逗号隔开的字符串去重,如:

//注意:这只能对相邻的字符串去重,因此要对字符串去重,必须先通过order by排序后去重
select regexp_replace((listagg(T.GROUP_CODE, ',') within group(order by T.PRODUCT_ID)),  '([^,]+)(,\1)*(,|$)','\1\3') GROUP_CODE from V_TEST t GROUP BY T.PRODUCT_ID
//以+号分割
regexp_replace((listagg(T.item_name, '+') within group(order by T.item_name)),  '([^\+]+)(\+\1)*(\+|$)','\1\3') item_name,
//或者
to_char(rtrim(xmlagg(xmlparse(content upper(item_name) || '+' wellformed) order by item_code).getclobval() ,'+')) item_name
//如果遇到字符串过长,则可以使用如下语句
regexp_replace(rtrim(xmlagg(xmlparse(content upper(product_id) || ',' wellformed) order by product_id).getclobval() ,','),'([^,]+)(,\1)*(,|$)', '\1\3') product_id,

//如果是mybatis中使用如下语句,否则会报错
regexp_replace((listagg(product_id, ',') within group(order by product_id)),  '([^,]+)(,\1)*(,|$)','\1\3') product_id

如下图所示:
在这里插入图片描述
去重后:
在这里插入图片描述

4、正则表达式如下:
‘^’ 匹配输入字符串的开始位置,在方括号表达式中使用,此时它表示不接受该字符集合。
‘$’ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘/n’ 或 ‘/r’。
‘.’ 匹配除换行符之外的任何单字符。
‘?’ 匹配前面的子表达式零次或一次。
‘+’ 匹配前面的子表达式一次或多次。
‘*’ 匹配前面的子表达式零次或多次。
‘|’ 指明两项之间的一个选择。例子’^([a-z]+|[0-9]+)$‘表示所有小写字母或数字组合成的字符串。
‘( )’ 标记一个子表达式的开始和结束位置。
‘[]’ 标记一个中括号表达式。
‘{m,n}’ 一个精确地出现次数范围,m=<出现次数<=n,’{m}‘表示出现m次,’{m,}'表示至少出现m次。
/num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。
字符簇:
[[:alpha:]] 任何字母。
[[:digit:]] 任何数字。
[[:alnum:]] 任何字母和数字。
[[:space:]] 任何白字符。
[[:upper:]] 任何大写字母。
[[:lower:]] 任何小写字母。
[[:punct:]] 任何标点符号。
[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]。
各种操作符的运算优先级
/转义符
(), (?😃, (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, anymetacharacter 位置和顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值