平时的oracle中的树查询我们一般都是在单表里存在这样的两个字段,id和p_id,当我们需要将这个单表里的数据以树的形式展示出来的时候,一般的sql写法是下面的这种写法
selec A.ID,A.NAME,A.P_ID from A start with a.id connect by prior id = p_id;
这条sql语句很好懂,在我当前这张表里进行查询,我的ID就是我的树查询开始的位置,后面的connect by 固定写法,这个prior的意思就是,我当前的ID是下一条数据的p_id.(如果 prior p_id = id 就是我当前的p_id 是下一条数据的ID)
也就是以当前ID为根,自顶向下进行查询。这是最简单的树查询,当然还有参数level,这里不做深究。
今天碰到一个问题,是将两张表的数据以树的形式展示出来,当时的我处于懵逼状态的,这怎么搞。后来去论坛里逛了一圈,发现了有人解决了这个问题。具体解决方案就是,就是两张表做一个union all 或者union查询。最后对这张新表进行树查询。
这么说可能不直接。下面那我的具体问题说。
这是预算科目表:BGT_SUBJECTS和预算类别表:BGT_SUBJECTS_TYPE,
可以看到BGT_SUBJECTS_TYPE表里有PID和ID,这里对应的实际业务场景为一级类别和以及类别下的二级类别,一级类别的PID是root,这里不做详细介绍。
在BGT_SUBJECTS表里也有ID和PID,这里对应的实际业务场景为具体的预算科目和预算科目的对应的预算类别。
这里就是要把这两张表的数据构建为一棵树,展示出来,基本效果就是:
-预算类别(BGT_SUBJECTS_TYPE -ID(root)-PID())
|----一级类别(BGT_SUBJECTS_TYPE-ID(1) -PID(root))
|-----二级类别(BGT_SUBJECTS_TYPE-ID(2) -PID(1))
|----预算科目(BGT_SUBJECTS -ID(3) -PID(2))
由于是两张表,我们先把需要的数据拿出来构造为一张表:
SELECT A.ID,A.PID,A.TABLE_NAME FROM BGT_SUBJECTS_TYPE A WHERE A.DR = 0
UNION ALL
SELECT B.ID ,B.PID,B.TABLE_NAME FROM BGT_SUBJECTS B WHERE B.DR =0
当我们构造完这个临时表之后,再对临时表里进行树查询的构造,也就是,
seelct * from (
SELECT A.ID,A.PID,A.TABLE_NAME FROM BGT_SUBJECTS_TYPE A WHERE A.DR = 0
UNION ALL
SELECT B.ID ,B.PID,B.TABLE_NAME FROM BGT_SUBJECTS B WHERE B.DR =0
) start with ID = 'root' connect by prior ID = PID
这样就成功的构造了两个表之间的树。需要注意的是,两个表关于父和子的关系要对应好。不要写错。
这里再说明一下:有的童鞋可能要问这俩表结构差不多直接一个表多好,这不是有病吗?为了证明我的脑子是正常的,我要说明一下,我只简单的列举了表里的部分字段,所以,实际情况中两个表的结构是不一样的,还有一点就是,产品在设计的时候这两张表里的数据在前台显示的时候也有不用的形式表现,so....你懂的哈。
另外附上这次解决问题的帖子,很感谢这里的各位。
解决问题的终点不是将问题的解决就算了,而是学会一种思想以及触类旁通。
ID | PID | TABLE_NAME |
预算科目表主键 | 预算类别主键 | BGT_SUBJECTS |
ID | PID | TABLE_NAME |
预算类别表主键 | 父ID | BGT_SUBJECTS_TYPE |