字符转换的SQL需求增强

上次《字符转换的SQL需求》讨论的需求,使用各种函数,实现了字符转换的需求,但通过朋友指教,其实存在些问题。


这是原来的写法,

SQL> SELECT listagg(x.a, ';') within GROUP (ORDER BY x.a) FROM
  2  (SELECT substr(regexp_substr(a, '[^,]+',1,level),3,7)||'.'||substr(regexp_substr(a, '[^,]+',1,level),0,2) AS a
  3  FROM test
  4  connect by level <= length(decode(substr(a,-1),',',substr(a,1,length(a)-1),a)) - length(REPLACE(a,',',''))+1x;

LISTAGG(X.A,';')WITHINGROUP(ORDERBYX.A)
--------------------------------------------------------
000001.SH;000002.SZ;000003.SZ


尚大师给出了regexp_replace和regexp_count的替代写法,

 
 
select listagg(regexp_replace(x.a, '([A-Z]{2})([0-9]{6})', '\2.\1'), ';') within group(order by x.a)from (select regexp_substr(a, '[^,]+', 1, level) afrom testconnect by level <= regexp_count(a, '[^,]+')) x;listagg(regexp_replace(x.a, '([A-Z]{2})([0-9]{6})''\2.\1'), ';'within group(order by x.a)
from (select regexp_substr(a, '[^,]+'1level) a
from test
connect by level <= regexp_count(a, '[^,]+')) x;


因为当时只测了一条数据的场景,所以用这种方法,对多条数据,是会有问题的,如下所示,test存在两条数据,执行SQL,并不是我们需要的结果,无法保证汇总后的顺序,

 
 
SQL> SELECT * FROM test;A------------------------------SH000001,SZ000002,SZ000003SX000001,SX000002,SX000003SQL> SELECT listagg(x.a, ';') within GROUP (ORDER BY x.a) FROM  2  (SELECT substr(regexp_substr(a, '[^,]+',1,level),3,7)||'.'||substr(regexp_substr(a, '[^,]+',1,level),0,2) AS a  3  FROM test  4  connect by level <= length(decode(substr(a,-1),',',substr(a,1,length(a)-1),a)) - length(REPLACE(a,',',''))+1) x;LISTAGG(X.A,';')WITHINGROUP(ORDERBYX.A)--------------------------------------------------------------------------------000001.SH;000001.SX;000002.SX;000002.SX;000002.SZ;000002.SZ;000003.SX;000003.SX;000003.SX;000003.SX;000003.SZ;000003.SZ;000003.SZ;000003.SZFROM test;
A
------------------------------
SH000001,SZ000002,SZ000003
SX000001,SX000002,SX000003

SQL> SELECT listagg(x.a, ';') within GROUP (ORDER BY x.a) FROM
  2  (SELECT substr(regexp_substr(a, '[^,]+',1,level),3,7)||'.'||substr(regexp_substr(a, '[^,]+',1,level),0,2) AS a
  3  FROM test
  4  connect by level <= length(decode(substr(a,-1),',',substr(a,1,length(a)-1),a)) - length(REPLACE(a,',',''))+1) x;

LISTAGG(X.A,';')WITHINGROUP(ORDERBYX.A)
--------------------------------------------------------------------------------
000001.SH;000001.SX;000002.SX;000002.SX;000002.SZ;000002.SZ;000003.SX;000003.SX;
000003.SX;000003.SX;000003.SZ;000003.SZ;000003.SZ;000003.SZ


尚大师给出了一种解法,很酷炫,这些地儿我还得再学学,引入了rownum做层级,并用rowid进行聚类,目的应该是保证同一个rowid的转换后还是同一行,很巧妙,

 
 
SQL> select listagg(regexp_replace(xx.a, '([A-Z]{2})([0-9]{6})', '\2.\1'), ';') within group(order by xx.rn) a  2  from (select x.rowid rid, regexp_substr(a, '[^,]+', 1, y.rn) a, y.rn  3  from test x, (select rownum rn from dual connect by rownum <= 5) y  4  where y.rn <= regexp_count(x.a, '[^,]+')) xx  5  group by rid;A--------------------------------------------------------------------------------000001.SH;000002.SZ;000003.SZ000001.SX;000002.SX;000003.SX'([A-Z]{2})([0-9]{6})', '\2.\1'), ';') within group(order by xx.rn) a
  2  from (select x.rowid rid, regexp_substr(a, '[^,]+', 1, y.rn) a, y.rn
  3  from test x, (select rownum rn from dual connect by rownum <= 5) y
  4  where y.rn <= regexp_count(x.a, '[^,]+')) xx
  5  group by rid;
A
--------------------------------------------------------------------------------
000001.SH;000002.SZ;000003.SZ
000001.SX;000002.SX;000003.SX


又碰见两个新的函数,

1. REGEXP_REPLACE函数,

REGEXP_REPLACE extends the functionality of the REPLACE function by letting you search a string for a regular expression pattern. By default, the function returns source_char with every occurrence of the regular expression pattern replaced with replace_string. The string returned is in the same character set as source_char. The function returns VARCHAR2 if the first argument is not a LOB and returns CLOB if the first argument is a LOB.


2. REGEXP_COUNT函数,

REGEXP_COUNT complements the functionality of the REGEXP_INSTR function by returning the number of times a pattern occurs in a source string. The function evaluates strings using characters as defined by the input character set. It returns an integer indicating the number of occurrences of pattern. If no match is found, then the function returns 0.


另外,朱大师给出了PG的解法,

640?wx_fmt=png


我只有EDB的库,虽然是PG的企业版,但这种写法,好像不支持,

640?wx_fmt=png


黄老师则指出,用Oracle的SQL可以直接在达梦中跑。


谢谢各位朋友,若还有好的建议,欢迎随时留言,谢谢。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、5资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值