天天看点

自我总结-oracle递归查询-一种查询结果的三种查询方式

去年八月,项目中需要查询出分类树的层级结构,根节点和各个叶子节点都存储在同一表中,通过某个id进行关联;

当时由于是初出茅庐,刚入职场,加上项目纳期比较赶,只求结果不问过程,便粗略了解了该表及关联属性表的结构,写了这样的查询语句:

select temp.name,t1.value as classname from (select t.name,t.ida2a2
 from LWCSTRUCTENUMATTTEMPLATE t start with t.ida2a2=468955 
 connect by prior t.ida3a4=t.ida2a2) temp,LWCLocalizablePropertyValue t1
 ,LWCPROPERTYDEFINITION t2 where t1.ida3b4=temp.ida2a2 and 
 t1.ida3a4=t2.ida2a2 and t2.name='displayName'
           

其主要是通过oracle的start with ...connect by prior 函数来查询出分类树的各个节点,再对查询结果通过    String.insert(0, rs.getString("classname") + "/")拼接得到;

后来项目需求增加,要通过叶子节点导入相关属性数据,需要获取到节点全路径与待导入路径匹配,仔细研究后发现节点表的关联关系与最开始理解的有所误差,于是便有了如下查询语句:

select t.Ida2a2,RPAD(' ',(LEVEL-1)*4)||t.NAME as name,
t.ida3a4,t2.value,LEVEL From LWCStructEnumAttTemplate t,LWCLocalizablePropertyValue t2 where
 t2.ida3b4=t.ida2a2 start with t.ida2a2=468955 connect by PRIOR t.ida3a4= t.ida2a2 order by Level desc;
           

仍是通过start with ...connect by prior 函数来获取节点的层级结构,通过level伪列来实现分层查询和排序,再从LWCLocalizablePropertyValue表中获取到相应的显示名称,仍旧是通过对查询结果进行字符串拼接得到分类全路径;

再后来细想,为什么非要再查询后再对查询结果进行字符串拼接呢?oracle是否有提供相关函数可以帮助实现呢?

经过查询资料后,得到如下查询语句:

select listagg(t2.value, '/')within group(order by Level desc) as classname
 from LWCSTRUCTENUMATTTEMPLATE t ,LWCLocalizablePropertyValue t2 where
 t2.ida3b4=t.ida2a2 start with t.ida2a2=468955 
 connect by prior t.ida3a4=t.ida2a2  ;
           

大体的查询思路还是递归查询那一套,只不过通过listagg()within group()函数来对查询结果进行拼接,即查询后一步到位,不需要再对查询结果遍历拼接了。