现在的位置: 首页 > 综合 > 正文

Oracle 递归查询

2014年09月05日 ⁄ 综合 ⁄ 共 2066字 ⁄ 字号 评论关闭

所谓递归查询就是“树状”查询,即:

select ... from tablename start with cond1 connect by cond2 where cond3

简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段:

id,parentid那么通过表示每一条记录的parent是谁,就可以形成一个树状结构。

用上述语法的查询可以取得这棵树的所有记录。

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

COND2是连接条件,其中用PRIOR表示上一条记录,比如
CONNECT BY PRIOR ID=PRAENTID
就是说上一条记录的ID是本条记录的PRAENTID,即本记录的父亲是上一条记录。

COND3是过滤条件,用于对返回的所有记录进行过滤。

PRIORSTART WITH关键字是可选项

PRIORY运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系,PRIOR运算符在一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。

在连接关系中,除了可以使用列名外,还允许使用列表达式。

START WITH
子句为可选项,用来标识哪个节点作为查找树型结构的根节点。若该子句被省略,则表示所有满足查询条件的行作为根节点。

下面给出一个例子:

CREATE TABLE SC_DISTRICT
(
  IID         NUMBER(10)                  NOT NULL,
  PARENT_ID  NUMBER(10),
  INAME       VARCHAR2(255 BYTE)          NOT NULL,
 BZ      NUMBER(4)
);
 
ALTER TABLE SC_DISTRICT ADD (
  CONSTRAINT SC_DISTRICT_PK
 PRIMARY KEY
 (IID));
 
ALTER TABLE SC_DISTRICT ADD (
  CONSTRAINT SC_DISTRICT_R01 
 FOREIGN KEY (PARENT_ID) 
 REFERENCES SC_DISTRICT (IID));
INSERT INTO SC_DISTRICT(IID,INAME) VALUES(1,'四川省');
 
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(2,1,'巴中市',0);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(3,1,'达州市',0); 
 
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(4,2,'巴州区',0);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(5,2,'通江县',0);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(6,2,'平昌县',0);
 
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(7,3,'通川区',0);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(8,3,'宣汉县',0);
 
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(9,8,'塔河乡',1);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(10,8,'三河乡',1);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(11,8,'胡家镇',1);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(12,8,'南坝镇',1);
 
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(13,6,'大寨乡',2);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(14,6,'响滩镇',2);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(15,6,'龙岗镇',2);
INSERT INTO SC_DISTRICT(IID,PARENT_ID,INAME,BZ) VALUES(16,6,'白衣镇',2);

--查询平昌县的子节点,即:自上而下查询,上一条数据的ID为父节点
SELECT * FROM SC_DISTRICT
START WITH INAME = '平昌县'
CONNECT BY PRIOR IID = PARENT_ID
 
--查询平昌县的父节点,即:自下而上查询,上一条数据的ID为子节点
SELECT * FROM SC_DISTRICT
START WITH INAME = '平昌县'
CONNECT BY PRIOR  PARENT_ID= IID

抱歉!评论已关闭.