oracle一张表的id关联另一张表中的字段

假设现在有两个表
表一:

idnumsnamescore
140643851小A87
140643856小B88
140643931小C92
140643611小D77
140643427小E81
140643155小F95
140643815小G78
140643492小H90
140643653小I71

表二:

idonameevent
1001小a小a在2017-10-19通知了学号为140643851,140643856的学生
1003小b小b在2017-10-03通知了学号为140643931的学生
1005小c小c在2017-10-08通知了学号为140643611,140643427,140643155的学生

表一的id是学号,表二的event中的数字就是学号,现在要查出这样的表

idonameidnumsname

那怎么做呢?
第一步,要把表二中的学号匹配出来吧?用正则表达式就好啦
‘[0-9]{9}(,[0-9]{9})*’
注意这里的数字是9位,后面可能有若干个逗号加数字,所以用括号括起来,用了‘*’
这个’*’就是零个或者多个的意思啦,{9}表示这样的数字有9位。有关正则可以看这一篇博客总结http://blog.csdn.net/yolanda_nuonuo/article/details/50524758

然后用oracle里的正则函数
regexp_substr(t.event, ‘[0-9]{9}(,[0-9]{9})*’),这个就可以把数字取出来了。

第二步,第一步的做法拿到的是这样的数字,这个表是test_tb,一个辅助中间表

value
140643851,140643856
140643931
140643611,140643427,140643155

但是要跟表一关联的话,需要的是这样的数字

学号
140643851
140643856
140643931
140643611
140643427
140643155

这个要怎么做呢?用connect by.

SELECT distinct regexp_substr(t.value, '[^,]+',1,level)
  FROM test_tb t
CONNECT BY t.value = PRIOR t.value
       AND LEVEL <= (length(t.value)-length(regexp_replace(t.value, ',', '')))+1
       AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL

说明:

这里的level就是一个层级的概念,比如吧

学号
140643851,140643856
140643931
140643611,140643427,140643155

这个第三列,有三个数,就有三层,level就要小于3

所以就要先算出这列有几个数据,可以用下面这句sql试一下

select t.value, (length(t.value)-length(regexp_replace(t.value, ',', '')))+1 from test_tb t

其实就是算出逗号的个数再加一就是有几个数。

最后的sql就是这样啦

select op.id, op.oname, tu.idnum, tu.sname from
(
select distinct to_number(regexp_substr(tb.value, '[^,]+',1,level)) as tid, tb.oid as oid from
(
select regexp_substr(o.event, '[0-9]{9}(,[0-9]{9})*') as value, o.id as oid from test_oper o
where regexp_substr(o.event, '[0-9]{9}(,[0-9]{9})*') is not null) tb
CONNECT BY TB.value = PRIOR TB.value
       AND LEVEL <= (length(tb.value)-length(regexp_replace(tb.value, ',', '')))+1
       AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
)
mm, test_stu tu, test_oper op
where mm.tid = tu.idnum
and mm.oid = op.id

结果就是
这里写图片描述

这里临时自定义了几个表,为了对应关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值