start with...connect by是根据条件递归查询树结构的数据
首先我们先创建一张表:
create table test_menu(
menu_id VARCHAR2(10) NOT NULL,
menu_name VARCHAR2(50) NOT NULL,
url VARCHAR2(50)NOT NULL,
style VARCHAR2(200)NOT NULL,
parent_id VARCHAR2(10) NOT NULL
);
添加数据如下:
查询树状结构数据表的语句如下:
select … from tablename
where 条件3
start with 条件1
connect by 条件2;
条件1 是根节点的限定语句,当然可以放宽限定条件,以取得多个根节点,实际就是多棵树。单条件START WITH 字段 = 值;多个根节点使用in: START WITH 字段 in(值,值,值)
条件2 是连接条件,其中用PRIOR表示上一条记录,比如 CONNECT BY PRIOR menu_id = parent_id;就是说上一条记录的menu_id 是本条记录的parent_id,即本记录的父亲是上一条记录。
条件3 是过滤条件,用于对返回的所有记录进行过滤。
关于PRIOR
运算符PRIOR被放置于等号前后的位置,决定着查询时的检索顺序。
第一种:PRIOR被置于CONNECT BY子句中等号的前面时,则强制从根节点到叶节点的顺序检索,即由父节点向子节点方向通过树结构,我们称之为自顶向下的方式。如:
CONNECT BY NOCYCLE PRIOR menu_id = parent_id
第二种:PIROR运算符被置于CONNECT BY 子句中等号的后面时,则强制从叶节点到根节点的顺序检索,即由子节点向父节点方向通过树结构,我们称之为自底向上的方式。例如:
CONNECT BY NOCYCLE menu_id = PRIOR parent_id
以下实现三种不同场景的查询方式:
从10005作为根节点开始,向下查询(包含menu_id=10005这条数据)语句如下,PRIOR的第一种检索顺序
SELECT t.* FROM test_menu t
START WITH t.menu_id = '10005'
CONNECT BY NOCYCLE PRIOR t.menu_id = t.parent_id;
查询结果:
从10005的根节点开始,向上查询(包含menu_id=10005这条数据)语句如下,PRIOR的第二种检索顺序
SELECT t.* FROM test_menu t
START WITH t.parent_id = '10005'
CONNECT BY NOCYCLE t.menu_id = PRIOR t.parent_id;
查询结果:
查询多个根节点,向下查询
SELECT t.* FROM test_menu t
START WITH t.menu_id in ('10002','10005')
CONNECT BY NOCYCLE PRIOR t.menu_id = t.parent_id;
查询结果: