我们假设有如下一张机构表(ORG):
字段类型 | 字段名称 | 字段描述 |
NUMBER(16) | ID | 机构ID |
NUMBER(16) | PARENT_ID | 父机构ID |
VARCHAR2(100) | NAME | 机构名称 |
NUMBER(1) | ENABLE | 是否启用,1表示启用,0表示停用 |
表中有如下几行数据:
ID | PARENT_ID | NAME | ENABLE |
1314 | 1399 | 信用卡后勤保障部 | 1 |
1399 | 5000 | 信用卡后勤部 | 1 |
1414 | 5000 | 信用卡业务部 | 0 |
5000 | 8888 | 信用卡总部 | 1 |
8888 | 9000 | 银行卡总部 | 1 |
9000 | 10000 | 业务部 | 1 |
10000 | -1 | 总部 | 1 |
在Oracle中,我们可以采用如下语句来进行递归查询:
select ID, PARENT_ID from ORG where [条件列表1] start with [递归起始条件] connect by prior [递归条件]
其中,条件列表1用来对查询出的所有的数据进行过滤,递归起始条件用于定义递归数据的起点,而递归条件用于定义递归的规则。
对于上面提到的ORG表,如果我们想查出信用卡后勤部的ID和它的所有启用的上级机构的ID,就可以用如下语句:
select ID from ORG where ENABLE = 1 start with ID = 1399 connect by prior PARENT_ID = ID
如上,我们要查的所有机构必须是启用的,所以在where语句后面加了ENABLE = 1这一全局条件,信用卡后勤部的机构ID为1399,所以我们在start with语句后面加了ID = 1399,我们得根据这个ID行的PARENT_ID来找出其父机构,又要根据其父机构的 PARENT_ID来找出父机构的父机构,以此类推,所以我们在connect by prior 语句后面加了PARENT_ID = ID。
下面给出查询结果:
ID |
1399 |
5000 |
8888 |
9000 |
10000 |
你可能会想到,如果把 connect by prior 语句后面的条件写成 ID = PARENT_ID,结果会怎样呢?
请看如下语句的结果:
select ID from ORG where ENABLE = 1 start with ID = 1399 connect by prior ID = PARENT_ID
ID |
1399 |
1314 |
你想的没错!它把信用卡后勤部及其下属部门的机构ID都查出来了,所以connect by prior 语句后面的条件“=”两边的条件顺序直接影响着结果!