如何实现Oracle子父节点查询
小白求助,如图,Oracle怎么实现图中的子父节点的递归查询呢。图中DICCOD字段是节点对应的组织代码,其中既有父节点又有子节点,DICDJ代表的是节点等级。以下是截图...
小白求助,如图,Oracle怎么实现图中的子父节点的递归查询呢。图中DICCOD字段是节点对应的组织代码,其中既有父节点又有子节点,DICDJ代表的是节点等级。以下是截图的一小部分。
展开
2个回答
展开全部
一般来说这种递归查询应该用start with connect by,不过你的表中少了一列,就是当前节点的父节点列,所以这个应该不能用。
比如元数据为4列 其中两列类似为
父节点编码 当前节点编码
010001000000 010001010000
010001010000 010001010200
那么start with connect by就可以用了,这里因为没有这个父节点编码的字段,所以不能用。
那么查询就麻烦一些,我想到了一个办法,不过是这个表结构的特例,希望能帮到你
第一步是截取输入的diccode的非零长度,我想到的办法是length(trim(tailing 0 from '输入或计算得到的diccode值'))--假设得到的是8位,假设为01000101 8位
那么所有的子节点就是 diccode like substr(diccode,1,length(trim(tailing 0 from '输入或计算得到的diccode值')))%
意思就是 diccode like '01000101%'(这不就是所有该节点的子节点了么,包括自身)
(以上部分的写法要斟酌一下,%是通配符,一般来说我们的写法是like ‘a%’,但是单引号部分怎么写,需不需要转译,反引号行不行,与%怎么连接,我没有环境只能写个大概意思,具体的要试验才行。)
然后求父节点,先求上一级,diccode=(case when length(trim(tailing 0 from '输入或计算得到的diccode值'))-2>0 then rpad(substr('输入或计算得到的diccode值',1, length(trim(tailing 0 from '输入或计算得到的diccode值'))-2),12,0) else 0 end)
意思就是:截取到01000101后,长度为8位,长度-2为6位那么就是010001,然后补足12位的0,为010001000000,也就是上一级父节点。如果输入为010000000000,那么第一步就直接查出所有内容了,后面这个条件用or连接,查出来的都是0,也就是diccode=0,不会干扰正常内容的显示。
然后继续-2变成-4(这样举例就变成为010000000000),再变成-6(例子中虽然也能查出来010000000000,但是前面已经查出,不会重复显示的),-8(例子中等于0,那么显示diccode=0,因为or连接所以不耽误显示),-10,我看了你的编码是12位,-10应该够了,写法同上,然后所有的条件用or连接,这样不用写过程去计算,虽然麻烦,而且速度不会太快,但是思路应该没错。
其实我一直在琢磨应该可以用start with connect by写后面的-2到-10部分,但是如果写成start那么这部分需要测试,我这里没有相关的环境,所以只能是这么写,麻烦一些。而且starwith好像没办法就相关子节点,所以我也不知道到底能不能用。
比如元数据为4列 其中两列类似为
父节点编码 当前节点编码
010001000000 010001010000
010001010000 010001010200
那么start with connect by就可以用了,这里因为没有这个父节点编码的字段,所以不能用。
那么查询就麻烦一些,我想到了一个办法,不过是这个表结构的特例,希望能帮到你
第一步是截取输入的diccode的非零长度,我想到的办法是length(trim(tailing 0 from '输入或计算得到的diccode值'))--假设得到的是8位,假设为01000101 8位
那么所有的子节点就是 diccode like substr(diccode,1,length(trim(tailing 0 from '输入或计算得到的diccode值')))%
意思就是 diccode like '01000101%'(这不就是所有该节点的子节点了么,包括自身)
(以上部分的写法要斟酌一下,%是通配符,一般来说我们的写法是like ‘a%’,但是单引号部分怎么写,需不需要转译,反引号行不行,与%怎么连接,我没有环境只能写个大概意思,具体的要试验才行。)
然后求父节点,先求上一级,diccode=(case when length(trim(tailing 0 from '输入或计算得到的diccode值'))-2>0 then rpad(substr('输入或计算得到的diccode值',1, length(trim(tailing 0 from '输入或计算得到的diccode值'))-2),12,0) else 0 end)
意思就是:截取到01000101后,长度为8位,长度-2为6位那么就是010001,然后补足12位的0,为010001000000,也就是上一级父节点。如果输入为010000000000,那么第一步就直接查出所有内容了,后面这个条件用or连接,查出来的都是0,也就是diccode=0,不会干扰正常内容的显示。
然后继续-2变成-4(这样举例就变成为010000000000),再变成-6(例子中虽然也能查出来010000000000,但是前面已经查出,不会重复显示的),-8(例子中等于0,那么显示diccode=0,因为or连接所以不耽误显示),-10,我看了你的编码是12位,-10应该够了,写法同上,然后所有的条件用or连接,这样不用写过程去计算,虽然麻烦,而且速度不会太快,但是思路应该没错。
其实我一直在琢磨应该可以用start with connect by写后面的-2到-10部分,但是如果写成start那么这部分需要测试,我这里没有相关的环境,所以只能是这么写,麻烦一些。而且starwith好像没办法就相关子节点,所以我也不知道到底能不能用。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询