您的位置:首页 > 数据库 > Oracle

oracle递归查询 start with connect by prior

2017-12-18 16:26 525 查看

(1)创建表结构

-- Create table
createtable TB_DW_JBXX
(
dwid    CHAR(10) notnull,
dwmc    VARCHAR2(100) notnull,
tcq     CHAR(2) notnull,
dwlx    CHAR(2) notnull,
dj      NUMBER(3) notnull,
yxzt    CHAR(1) notnull,
lsdwid  CHAR(10) notnull,
dwid_dxt CHAR(10)
)
tablespace DATA
pctfree10
initrans1
maxtrans255
storage
(
initial64K
minextents1
maxextentsunlimited
);
-- Add comments to thecolumns
commentoncolumn TB_DW_JBXX.dwid is'单位ID';
commentoncolumn TB_DW_JBXX.dwmc  is'单位名称';
commentoncolumn TB_DW_JBXX.tcq  is'所属统筹区';
commentoncolumn TB_DW_JBXX.dwlx  is'单位类型';
commentoncolumn TB_DW_JBXX.dj
is'单位等级 0:路局;1:社保中心;2......n:基层单位';
commentoncolumn TB_DW_JBXX.yxzt is'有效状态 0:有效;1:无效';
commentoncolumn TB_DW_JBXX.lsdwid is'隶属的上层单位';
commentoncolumn TB_DW_JBXX.dwid_dxt is'单位ID_大系统';
-- Create/Recreateprimary, unique and foreign key constraints
altertable TB_DW_JBXX
addconstraint PK_TB_DW_JBXX primarykey (DWID)
usingindex
tablespace INDX
pctfree10
initrans2
maxtrans255
storage
(
initial64K
minextents1
maxextentsunlimited
);
-- Grant/Revoke objectprivileges
grantselecton TB_DW_JBXX toGUEST_XX;


(2)插入数据,略

树结构:

 


(3)语法说明

connect by 是结构化查询中用到的,其基本语法是:
select … from tablename

where 条件3

start with 条件1

connect by 条件2;


   

条件1 是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。

条件2 是连接条件,其中用PRIOR表示上一条记录
条件3 是过滤条件,用于对返回的所有记录进行过滤

 

start with 子句:遍历起始条件,

START WITH 可以省略:不指定树的根,默认把Tree整个表中的数据从头到尾遍历一次,每一个数据做一次根,然后遍历树中其他节点信息.

connect by 子句:连接条件。STARTWITH 与CONNECT BY PRIOR位置可互换

 

关键词prior

  prior跟父节点列lsdwid放在一起,就是往父结点方向遍历;

  prior跟子结点列dwid放在一起,则往叶子结点方向遍历,

  lsdwid、dwid两列,谁放在“=”前都无所谓,关键是prior跟谁在一起。

  prior位置决定了检索是自底向上还是自顶向下

  "prior" 如果缺省:则只能查询到符合条件的起始行,并不进行递归查询。 

orderby 子句:排序,不用多说。

 

(4)测试

--0900000002(上海) /0900000001 (全局)

--用例(1)

SELECT * FROM tb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002'CONNECT BY PRIOR d.dwid=d.lsdwid;
SELECT * FROM tb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002'CONNECT BY d.lsdwid= PRIOR d.dwid;


以上sql语句查询结果是一样的。结果如下:



数据分析:

123条数据,(包含当前节点数据)自顶向下、向子节点方向遍历。

如果想获取当前节点的所有子节点(不包含当前节点),可以直接取lsdwid这列数据。或使用用例(2)语句。

"prior" 如果缺省:则只能查询到符合条件的起始行,并不进行递归查询。 

SELECT * FROM tb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002' CONNECT BY  d.dwid=d.lsdwid;


数据结果略。

 

--用例(2)

SELECT * FROMtb_dw_jbxx d WHERE d.yxzt='0' START WITH d.lsdwid='0900000002' CONNECT BY PRIORd.dwid=d.lsdwid;


结果数据如下所示:



数据分析:

122条数据,(不包含当前节点数据)自顶向下、向子节点方向遍历。

 

--用例(3)

SELECT * FROMtb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002' CONNECT BY  d.dwid= PRIOR d.lsdwid;

结果数据如下所示:



数据分析:

2条数据,(包含当前节点数据)自底向上、向子节点方向遍历。

如果想获取当前节点的所有父节点(不包含当前节点),可以直接取lsdwid这列数据。

--用例(4)

SELECT * FROMtb_dw_jbxx d WHERE /*d.yxzt='0' AND*/ d.lsdwid='0900000002' ;
SELECT * FROMtb_dw_jbxx d WHERE d.yxzt='0' START WITH d.lsdwid='0900000002' CONNECT BYd.dwid=  PRIOR d.lsdwid;

数据结果如下所示:



数据分析:

266条数据,(包含当前节点数据)自底向上、向子节点方向遍历。

如果想获取当前节点的所有父节点(不包含当前节点),可以直接取lsdwid这列数据。

'0900000002'下的一级子单位94条(SELECT * FROMtb_dw_jbxx d WHERE /*d.yxzt='0' AND*/ d.lsdwid='0900000002'),其中有效的78条,无效的16条。

266条数据中,94条全局的数据,94条上海的数据,78条子节点数据。

本来以为会,78条全局的数据,78条上海的数据,78条子节点数据。

而实际数据却是,94,94,78;

查询原因:是16条无效的数据,也递归查询父节点。

所以:where 语句,可以看成与递归查询无关。只是对整个结果起过滤作用。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: