Oracle 递归查询 start with... connect by prior...

Oracle 递归查询 start with… connect by prior…

-- 语法
select column from table 
start with ...
connect by prior ...

Oracle 递归查询是以start with 后的条件筛选出主干,然后通过主干结合connect by 条件查找分支,最终形成树状结构。下面通过示例进行说明:

-- 构建环境
CREATE TABLE T_TEST_AREA(
	ID INT,
	PID INT,
	NAME VARCHAR2(20),
	DELETED INT,
	CHECKED INT
);

DELETE FROM T_TEST_AREA WHERE 1=1;
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(1, -1, '长沙市', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(2, -1, '深圳市', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(3, 1, '开福区', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(4, 1, '雨花区', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(5, 1, '岳麓区', 0, 0);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(6, 2, '宝安区', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(7, 2, '南山区', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(8, 2, '福田区', 0, 0);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(9, 4, '黎托街道', 0, 1);
INSERT INTO T_TEST_AREA(ID, PID, NAME, DELETED, CHECKED) VALUES(10, 4, '东山街道', 0, 1);

-- 查询
ID|PID|NAME|DELETED|CHECKED|
--|---|----|-------|-------|
 1| -1|长沙市 |      0|      1|
 2| -1|深圳市 |      0|      1|
 3|  1|开福区 |      0|      1|
 4|  1|雨花区 |      0|      1|
 5|  1|岳麓区 |      0|      0|
 6|  2|宝安区 |      0|      1|
 7|  2|南山区 |      0|      1|
 8|  2|福田区 |      0|      0|
 9|  4|黎托街道|      0|      1|
10|  4|东山街道|      0|      1|

1、 从上往下查找

SELECT * FROM T_TEST_AREA 
START WITH PID = -1       -- 筛选主干
CONNECT BY PRIOR ID = PID; -- prior修饰的是主干的字段,筛选PID=主干ID的数据作为分支数据

-- 此种写法结果同上,但不建议使用这种写法
SELECT * FROM T_TEST_AREA START WITH PID = -1 CONNECT BY PID = PRIOR ID;

-- result
ID|PID|NAME|DELETED|CHECKED|
--|---|----|-------|-------|
 1| -1|长沙市 |      0|      1|
 3|  1|开福区 |      0|      1|
 4|  1|雨花区 |      0|      1|
 9|  4|黎托街道|      0|      1|
10|  4|东山街道|      0|      1|
 5|  1|岳麓区 |      0|      0|
 2| -1|深圳市 |      0|      1|
 6|  2|宝安区 |      0|      1|
 7|  2|南山区 |      0|      1|
 8|  2|福田区 |      0|      0|

2、 从下往上查找

SELECT * FROM T_TEST_AREA START WITH ID = 10 CONNECT BY PRIOR PID = ID;
SELECT * FROM T_TEST_AREA START WITH ID = 10 CONNECT BY ID = PRIOR PID;

-- result
ID|PID|NAME|DELETED|CHECKED|
--|---|----|-------|-------|
10|  4|东山街道|      0|      1|
 4|  1|雨花区 |      0|      1|
 1| -1|长沙市 |      0|      1|

3、通用递归(无法形成树状顺序)

WITH ALLSUB(ID, PID, NAME, DELETED, CHECKED) AS(
-- 主干
SELECT ID, PID, NAME, DELETED, CHECKED FROM T_TEST_AREA WHERE PID = -1
UNION ALL
-- 分支
SELECT A.ID, A.PID, A.NAME, A.DELETED, A.CHECKED FROM T_TEST_AREA A, ALLSUB B WHERE A.PID = B.ID
)
SELECT ID, PID, NAME, DELETED, CHECKED FROM ALLSUB;

-- result
ID|PID|NAME|DELETED|CHECKED|
--|---|----|-------|-------|
 1| -1|长沙市 |      0|      1|
 2| -1|深圳市 |      0|      0|
 3|  1|开福区 |      0|      1|
 4|  1|雨花区 |      0|      1|
 5|  1|岳麓区 |      0|      0|
 6|  2|宝安区 |      0|      1|
 7|  2|南山区 |      0|      1|
 8|  2|福田区 |      0|      0|
 9|  4|黎托街道|      0|      1|
10|  4|东山街道|      0|      1|
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值