Oracle处理以,隔开存储的数据

,隔开的字符串。我们需要管理这个字符串,使其中包含某个测点标识的数据去掉,你会如何做呢(思考一会)?

一开始想到的是字符串替换,后面发现这种方式不好,有异常情况发生(某个测点标识包含另一个测点标识时会发生异常),而且要考虑的情况比较多。

这种方式不行,那更好的方式是什么?

从数据存储的结构上来看,我们最好的存储方式是一个测点标识一条记录,这样就可以区分开了,既然这样我们如何将数据分割开来呢?

一个一个找?是的,其实就是这样。

:a,b,c,d

首先找到a,接着找到b,依次下去找到最后一个d

首先分析数据的结构(多种角度):

1a 第一个逗号 b 第二个逗号 c 第三个逗号 d

2非逗号 逗号非逗号逗号非逗号非逗号

3第一个非逗号 逗号第二个非逗号逗号第三个非逗号逗号第四个非逗号

。。。。

数据始终是有规律的,数据有两个格式:逗号和非逗号,同时它们都有位置信息。

我们可以结合这个信息找到其中的信息。

Oracle中有个函数:

function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier)

__srcstr     :需要进行正则处理的字符串

__pattern    :进行匹配的正则表达式

__position   :起始位置,从第几个字符开始正则表达式匹配(默认为1

__occurrence :标识第几个匹配组,默认为1

__modifier   :模式('i'不区分大小写进行检索;'c'区分大小写进行检索。默认为'c'。)

其中的patternoccurrence是这个问题求解的关键所在。

模拟这个过程:

SELECT REGEXP_SUBSTR('a,b,c,d','[^,]+',1,1)AS STRFROM DUAL;  

SELECT REGEXP_SUBSTR('a,b,c,d','[^,]+',1,2)AS STRFROM DUAL;

SELECT REGEXP_SUBSTR('a,b,c,d','[^,]+',1,3)AS STRFROM DUAL;  

SELECT REGEXP_SUBSTR('a,b,c,d','[^,]+',1,4)AS STRFROM DUAL;

 

上面这些sql,唯一不同的就是匹配的是第几个匹配组。

那我们能不能通过辅助表产生这些递增的匹配组索引信息,当然能

SELECT LEVEL FROM DUAL CONNECT BY LEVEL <=7;  

产生1-7的递增索引,结合上面的例子来做

 

这样会有额外的空数据,那么我们需要确定到底有少个逗号

LENGTH('a,b,c,d')-LENGTH(REPLACE('a,b,c,d',',',''))+1

 

结合到我们的业务上,需要移除指定测点标识的数据,先拆分成多行,再通过指定的测点标识进行过滤,最后通过wm_concat函数重组剩下满足的测点标识

SELECT  WM_CONCAT(PJCDDM) AS PJCDDM

   FROM  

   (SELECT SUBDY.XH,REGEXP_SUBSTR(SUBDY.PJCDDM,'[^,]+',1,L) AS  PJCDDM,  

       FROM T_JCSJZX_PJFW_DBSDY SUBDY,  

       (SELECT LEVEL L FROM DUAL CONNECT BY LEVEL<=150)  

          WHERE L<=LENGTH(SUBDY.PJCDDM) -LENGTH(REPLACE(SUBDY.PJCDDM,','))+1                ORDER BY SUBDY.PJCDDM  

      ) DY WHERE DY.PJCDDM !=  过滤的测点 AND DY_MAIN.XH = DY.XH GROUP BY DY.XH  

 

注:mysql中同样的思路只是查找数据的函数(substring_index)稍有不同而已

 

最终sql:

UPDATE T_JCSJZX_PJFW_DBSDY DY_MAIN SET(PJCDDM,PJCDMC) = (

       SELECT  WM_CONCAT(PJCDDM) AS PJCDDM, WM_CONCAT(PJCDMC) AS PJCDMC

       FROM

       (SELECT SUBDY.XH,REGEXP_SUBSTR(SUBDY.PJCDDM,'[^,]+',1,L) AS  PJCDDM,

               REGEXP_SUBSTR(SUBDY.PJCDMC,'[^,]+',1,L) AS  PJCDMC

               FROM T_JCSJZX_PJFW_DBSDY SUBDY,

               (SELECT LEVEL L FROM DUAL CONNECT BY LEVEL<=150)

               WHERE L<=LENGTH(SUBDY.PJCDDM) -LENGTH(REPLACE(SUBDY.PJCDDM,','))+1

               ORDER BY SUBDY.PJCDDM,SUBDY.PJCDMC

        ) DY WHERE DY.PJCDDM != '530700FB2501000201' AND DY_MAIN.XH = DY.XH GROUP BY DY.XH

) WHERE INSTR(','||DY_MAIN.PJCDDM||',', ','||'530700FB2501000201'||',') > 0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来了就走下去

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值