Oracle 樹狀 父子結點 查詢方法 倒敘查詢

2021-10-24 18:21:58 字數 4941 閱讀 5180

旨在記錄一些oracle使用中遇到的各種各樣的問題. 同時希望能幫到和我遇到同樣問題的人.

問題描述:

在資料庫中, 有一種比較常見得 設計模式, 層級結構 設計模式, 具體到 oracle table中, 字段特點如下:

id, dsc, pid;

三個字段, 分別表示 當前標識的 id(主鍵), dsc 當前標識的描述, pid 其父級id, 比較典型的例子 是 國家, 省, 市 這種層級結構;

省份歸屬於國家, 因此 pid 為 國家的 id, 以此類推;

create

table demo (

id varchar2(10) primary key,

dsc varchar2(100),

pid varchar2(10)

)--插入幾條資料

insert

into demo values ('00001', '中國', '-1');

insert

into demo values ('00011', '陝西', '00001');

insert

into demo values ('00012', '貴州', '00001');

insert

into demo values ('00013', '河南', '00001');

insert

into demo values ('00111', '西安', '00011');

insert

into demo values ('00112', '咸陽', '00011');

insert

into demo values ('00113', '延安', '00011');

這樣子就成了乙個簡單的樹級結構, 我一般將 根節點的 pid 定為 -1;

start with:

基本語法如下:

select ... from    + 表名

where + 條件3

start

with + 條件1

connect

byprior + 條件2

--示例

select * from demo

start

with

id = '00001'

connect

byprior

id = pid

條件1: 表示從哪個節點開始查詢, 也就是通過條件1 查詢到的資料, 作為後續查詢的起始節點(引數).

當然可以放寬限定條件,如 id in ('00001', '00011')以取得多個根節點,也就是多棵樹;在連線關係中,除了可以使用列明外,還允許使用列表示式。

如果省略start with

就預設把所有滿足查詢條件的tree整個表中的資料從頭到尾遍歷一次,每乙個資料做一次根,然後遍歷樹中其他節點資訊.

條件2: 是連線條件,其中用prior表示上一條記錄,例如connect by prior id = pid,意思就是上一條記錄的id是本條記錄的pid,即本記錄的父親是上一條記錄。connect by子句說明每行資料將是按照層次順序檢索,並規定將表中的資料連入樹形結構的關係中。

prior 在父節點的一側表示, 自底向上查, 在 子節點的一側表示 自上向下查詢;

條件3: 不能用在 connect by 後, 這裡的條件判斷, 等價於 在最後查詢出結果列表之後, 再進行條件篩選; 並非 刪除掉 節點及子節點;

--自底向上

select * from demo

start

with

id = '00113'

connect

byprior pid = id

--結果

00113 延安 00011

00011 陝西 00001

00001 中國 -1

--自上向下

select * from demo

start

with

id = '00001'

--用 start wiht pid = '-1' 結果不變

connect

byprior

id = pid

--結果

00001 中國 -1

00011 陝西 00001

00111 西安 00011

00112 咸陽 00011

00113 延安 00011

00012 貴州 00001

00013 河南 00001

--where 刪除

select

id, pid, dsc

from demo

where

id<> '00011'

start

with

id = '00001'

connect

byprior

id = pid

--結果

00001 -1 中國

00111 00011 西安

00112 00011 咸陽

00113 00011 延安

00012 00001 貴州

00013 00001 河南

下面是幾條關鍵字特殊點:

nocycle關鍵字, 有時候資料本身 不合理會導致出現迴圈的問題, 如 將上述的 id '00001' 記錄的 'pid' 也改為 '00001', 會出現迴圈的問題, 這是, 需要用到 nocycle 即可消除迴圈;

connect by nocycle prior id = pid 即可.

connect_by_isleaf 表示當前節點是否是葉子節點

level 表示當前節點所處層級, 這裡的層級指的是 從 start with 查詢到的節點開始往下算起, 當前屬於第幾層級

select

id, pid, dsc,

connect_by_isleaf isleaf,

level

from demo

connect

bynocycle

prior

id = pid

start

with

id = '00001';

--結果

id pid dsc isleaf level

00001 00001 中國 0 0

00011 00001 陝西 0 1

00111 00011 西安 1 2

00112 00011 咸陽 1 2

00113 00011 延安 1 2

00012 00001 貴州 1 1

00013 00001 河南 1 1

這裡需要注意的乙個點, 如果採用的是 自底向上的 方式查詢, 則 level 的 層級 同樣是 從底向上, 如 00113 level 1 00011 level 2 00001 level 3.

另外一點: 如果在查詢語句中 select id, pid, dsc, connect_by_isleaf isleaf, level - 1 level 這種查詢方式的話, 在 where 判斷條件中, 只需要判斷 level = 1, 就可以取出 當前查詢節點的 子節點(由於level 也是 偽列, 需要用子查詢的方式);

siblings關鍵字:它會保護層次,並且在每個等級中按expre排序。

select

id, pid, dsc,

connect_by_isleaf,

level

from demo

start

with

id = '00001'

connect

bynocycle

prior

id = pid

order

by dsc

--結果, 僅貼出部分資料(層級結構被破壞了)

00012 00001 貴州 1 2

00013 00001 河南 1 2

00011 00001 陝西 0 2

00111 00011 西安 1 3

00112 00011 咸陽 1 3

00113 00011 延安 1 3

00001 -1 中國 0 1

--order siblings by dsc

select

id, pid, dsc,

connect_by_isleaf,

level

from demo

start

with

id = '00001'

connect

bynocycle

prior

id = pid

order

siblings

by dsc

--結果(level 層級不變)

00001 -1 中國 0 1

00012 00001 貴州 1 2

00013 00001 河南 1 2

00011 00001 陝西 0 2

00111 00011 西安 1 3

00112 00011 咸陽 1 3

00113 00011 延安 1 3

connect_by_iscycle:存在迴圈,將返回1,否則返回0

Oracle 樹狀查詢

筱公尺加步槍 posted 2010年8月18日 23 01 in 資料庫 with tags oracle 樹狀,950 閱讀 在實際應用中,經常利用資料庫儲存樹狀結構的資料,通常用一張表中的兩個字段表示,乙個是自身的id,乙個是儲存父類的id。在這樣具有這種關係中的資料,要求查出的資料具有我們想...

oracle 樹狀查詢

connect by 是結構化查詢中用到的,其基本語法是 select from tablename start with 條件1 connect by 條件2 where 條件3 例 select from table start with org id hbhqfwgwpy connect by...

oracle 樹狀查詢

connect by 是結構化查詢中用到的,其基本語法是 select from tablename start with 條件1 connect by 條件2 where 條件3 例 select from table start with org id hbhqfwgwpy connect by...