一、start with.....connect by递归查询
建表语句:
CREATE TABLE D_ZONECODE ( ID VARCHAR2(36) NOT NULL UNIQUE, ZONECODE VARCHAR2(6) NOT NULL, SUPERCODE VARCHAR2(6) NOT NULL, ZONELLEVEL VARCHAR2(2) NOT NULL, ZONENAME VARCHAR2(60) NOT NULL );
插入数据语句:
INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('1', '370000', '000000', '01', '山东省'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('2', '370100', '370000', '02', '济南市'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('3', '370102', '370100', '03', '历下区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('4', '370103', '370100', '03', '市中区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('5', '370104', '370100', '03', '槐荫区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('6', '370105', '370100', '03', '天桥区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('7', '370112', '370100', '03', '历城区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('8', '370113', '370100', '03', '长清区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('9', '370114', '370100', '03', '高新区'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('10', '370124', '370100', '03', '平阴县'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('11', '370125', '370100', '03', '济阳县'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('12', '370126', '370100', '03', '商河县'); INSERT INTO D_ZONECODE (ID, ZONECODE, SUPERCODE, ZONELLEVEL, ZONENAME) VALUES ('13', '370181', '370100', '03', '章丘市');
root向树末梢查询:
select * from d_zonecode start with id=’370000’ connect by prior zonecode = supercode;
树末梢向ROOT查询:
select * from d_zonecode start with zonecode = '370100' connect by prior supercode = zonecode;
附:
start with指明从哪里开始遍历树
connect by 就是指明父子关系,注重PRIOR位置
CONNECT_BY_ROOT: 提供获取根节点记录的字段信息。
二、 今天客户突然要一个表格,这里面包括两个表的总分关系,比如我要显示部门同时和该部门下的所有人员用一条记录显示,在网上搜到一个例子,记录下方便使用。
建表语句:
/* Create Tables */ CREATE TABLE DEPT ( ID VARCHAR2(36) NOT NULL UNIQUE, DEPTID VARCHAR2(4) NOT NULL UNIQUE, DEPTNAME VARCHAR2(60) NOT NULL ); CREATE TABLE D_USER ( ID VARCHAR2(36) NOT NULL UNIQUE, USERID VARCHAR2(6) NOT NULL UNIQUE, USERNAME VARCHAR2(60) NOT NULL, DEPTID VARCHAR2(4) NOT NULL );
插入数据语句:
-- 部门表 INSERT INTO dept (id, deptid, deptname) VALUES ('1', '0001', '市场部'); INSERT INTO dept (id, deptid, deptname) VALUES ('2', '0002', '开发部'); INSERT INTO dept (id, deptid, deptname) VALUES ('3', '0003', '项目部'); -- 用户表 INSERT INTO D_USER (id, userid, username, deptid) VALUES ('1', '100001', '张肃宁', '0001'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('2', '100002', '王济南', '0002'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('3', '100003', '赵临沂', '0001'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('4', '100004', '金淄博', '0003'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('5', '100005', '李德州', '0002'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('6', '100006', '周济宁', '0001'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('7', '100007', '姜潍坊', '0003'); INSERT INTO D_USER (id, userid, username, deptid) VALUES ('8', '100008', '万青岛', '0001');
查询:
select * from dept t; select * from d_user t;
select username from ( select row_number() over(order by lv desc) id,username,deptid from ( select level lv, replace(sys_connect_by_path(username,','),',',',') username,deptid from( select deptid,username,row_number() over(order by username) id from ( select a.deptid,a.deptname,b.username from dept a,d_user b where a.deptid = b.deptid ) ) connect by prior id = id-1 )) where id = 1;
要是需要和部门连接查询,我采用建立一个方法,然后查询部门记录时调用该方法,传部门id这个参数进去。
--方法建立: create or replace function getUsername(oc_deptid in varchar2 ) return varchar2 is oc_result varchar(300); oc_username varchar2(300); -- 取值 begin --查询用户名称 select username into oc_result from ( select row_number() over(order by lv desc) id,username,deptid from ( select level lv, replace(sys_connect_by_path(username,','),',',',') username,deptid from( select deptid,username,row_number() over(order by username) id from ( select a.deptid,a.deptname,b.username from dept a,d_user b where a.deptid = b.deptid and a.deptid = oc_deptid ) ) connect by prior id = id-1 )) where id = 1; oc_username:=oc_result; if oc_result is NULL then oc_username := ''; else oc_username := SUBSTR(oc_result,INSTR(oc_result,',')+1,LENGTH(oc_result)-1); end if; return oc_username; end;
查询sql:
select t.deptid,t.deptname,getUsername(t.deptid) as username from dept t;
附(CONNECT_BY_ROOT使用):
select zonecode,zonename,CONNECT_BY_ROOT(zonecode) as root_code from d_zonecode start with zonecode = '370100' connect by prior zonecode = supercode and zonecode != supercode; select zonecode,CONNECT_BY_ROOT(zonecode) as root_code from d_zonecode start with zonecode = '370114' connect by prior supercode = zonecode and zonecode != supercode; select CONNECT_BY_ROOT(t.zonecode) as ROOT from d_zonecode t where t.zonecode = '370100' start with t.zonecode = t.supercode connect by prior t.zonecode = t.supercode and t.zonecode != t.supercode;