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 位置和顺序