(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 语句,可以看成与递归查询无关。只是对整个结果起过滤作用。