日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle connet by prior 关键字的简单介绍和用法

發(fā)布時(shí)間:2025/3/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle connet by prior 关键字的简单介绍和用法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.



??????? 簡單來講,?? connect by piror 這個(gè)關(guān)鍵字是用來保存樹結(jié)構(gòu)的關(guān)系表的.

???

一, 樹結(jié)構(gòu)簡單介紹


? ?? ?? 這里都簡單解釋一下樹結(jié)構(gòu),?? 所謂樹就是里面的成員除了最上級(jí)的成員外,? 有且只有一個(gè)上級(jí)成員,? 而且可以n個(gè)下級(jí)成員(n>=0). 最上級(jí)的成員沒有上級(jí)成員.

??????? 在現(xiàn)實(shí)中, 一間公司的人事結(jié)構(gòu)可以用樹來表示啦, 前提是1個(gè)員工不能有兩個(gè)直屬上司, 不然都不知道聽哪個(gè)啊是不是.


??????? 當(dāng)然, 上面的解釋是不嚴(yán)謹(jǐn)?shù)? 嚴(yán)謹(jǐn)?shù)慕馕鼍鸵プx一讀數(shù)據(jù)結(jié)構(gòu)啦.


二, 雙親表示法保存樹結(jié)構(gòu).


2.1 存儲(chǔ)原理

? ? ? ? ? 例如我要保存1個(gè)簡單的人事結(jié)構(gòu)如下圖:

? ? ? ? ??

? ? ? ? ? ? ? ? ? 1. Nedved

? ? ? ? ? ? ? ? ? ? ? / ? ? ? ? ? \ ??

???????? 2. Jason?????? 3.Hebe

??????????? /????? ? ? ? \

? 4.David??????? 5.Peter

???????????????????????? /???????? \

???????????????? 6. Jacky??? 7.Bill


??????? 怎么把上面的結(jié)構(gòu)保存入數(shù)據(jù)庫的一張表?? 通常的做法是為表里的成員設(shè)置1個(gè)唯一的key (id), 而且設(shè)置1個(gè)parent_id, 存放的是這個(gè)成員的父成員的id.

??????? 這種利用id 和 parent_id 來表示樹結(jié)構(gòu)的方法實(shí)際上就是 "雙親表示法" 詳細(xì)可以參考下面鏈接:

??????? http://blog.csdn.net/nvd11/article/details/8872842


2.2 建表

???????? 了解原理后, 建表就很簡單了, 總之這張表必須包含3個(gè)列,? 分別是 id, name , p_id


create table tree_1(id numeric(6),name varchar(20),p_id numeric(6));

2.3 插入數(shù)據(jù)

???????? 插入數(shù)據(jù)也不難,? 只需要知道每個(gè)數(shù)據(jù)列的父級(jí)就ok.?? 但是我們上面提過了, 最上級(jí)的成員(Nedved) 是沒有父級(jí)的, 一般會(huì)將Nedved行的p_id 設(shè)成NULL,? 但是這種情況有時(shí)會(huì)影響檢索(索引失效),? 所以我們盡量避免NULL值出現(xiàn)在表中, 所以最好把Nedved的p_id 設(shè)成0.


????????? 插入數(shù)據(jù)的語句如下:

delete from tree_1;insert into tree_1 values(1, 'Nedved' , 0); insert into tree_1 values(2, 'Jason' , 1); insert into tree_1 values(3, 'Hebe' , 1); insert into tree_1 values(4, 'David' , 2); insert into tree_1 values(5, 'Peter' , 2); insert into tree_1 values(6, 'Jacky' , 5); insert into tree_1 values(7, 'Bill' , 5); commit;
好了, 到這步為止我們已經(jīng)把1個(gè)簡單的樹結(jié)構(gòu)保存如一張關(guān)系數(shù)據(jù)表啦.



三, 檢索數(shù)據(jù)

3.1 查找某個(gè)節(jié)點(diǎn)的父節(jié)點(diǎn)

?????? 這個(gè)很簡單了,? 例如我想查找Jason上司是誰? (已知Jason的id是2)

?????? 直接根據(jù)pid查找就ok啦.

select a.* from tree_1 a, tree_1 b where a.id = b.p_id and b.id = 2
輸出: ID NAME P_ID ---------- -------------------- ----------1 Nedved 0


3.2 查找某個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn).

這里的子節(jié)點(diǎn)是直某個(gè)節(jié)點(diǎn)的下一級(jí)的節(jié)點(diǎn). 例如我想查找Jason的直接下屬. 那么就應(yīng)該找出David 和 Peter,? 而Peter的下屬Jacky和Bill就不屬于Jason的子節(jié)點(diǎn)了.


方法都很簡單,? 查找p_id的值是Jason的id就ok啦.

SQL> select * from tree_1 where p_id = 2 /*Jason's id*/;ID NAME P_ID ---------- -------------------- ----------4 David 25 Peter 2SQL>

3.3 查找某個(gè)節(jié)點(diǎn)的所有子孫節(jié)點(diǎn).

這里的子孫就龐大了,? 實(shí)際就是找1個(gè)節(jié)點(diǎn)的所有后代節(jié)點(diǎn),?

例如我想找Jason的所有后代節(jié)點(diǎn):

首先 當(dāng)然包括David 和 Peter啦, 而Peter的后代也是Jason的后代啊, 所以要把Jacky 和 Bill也找出來.


這里看來并不復(fù)雜啊, 是因?yàn)槲疫@個(gè)樹結(jié)構(gòu)太淺了, 實(shí)際上常規(guī)的sql語句寫法是很難實(shí)現(xiàn)的,? 假如Bill也有后代....? 也就是說很難根據(jù)1個(gè)節(jié)點(diǎn)判斷他的最深的后代去哪一層啊.


當(dāng)然利用循環(huán)和臨時(shí)表是能解決問題的, 但是sql語句就相當(dāng)復(fù)雜了.


Oracle中有個(gè)關(guān)鍵字" connect by "? 就是在這種情況下發(fā)揮作用的, 通常和"start with"字句一同使用.


例如這個(gè)小節(jié), 我要找出Jason的所有直接和非直接的下屬.

就可以利用如下語句:

select * from tree_1 start with id = 2 --Jason's id connect by prior id = p_id;

輸出:

ID NAME P_ID ---------- -------------------- ----------2 Jason 14 David 25 Peter 26 Jacky 57 Bill 5
我們來分析下這條語句:

1)? 首先? connect by prior id = p_id?? 也可寫成 connect by p_id = prior id, 關(guān)鍵是prior的位置是在 id 的前面還是 parent id 的前面.


2) 如果prior 關(guān)鍵字在id前面, 就相當(dāng)對(duì)1個(gè)樹從根節(jié)點(diǎn)往下面遍歷所有節(jié)點(diǎn)了!

3) 例如上面例子,? start with字句就是用來決定跟節(jié)點(diǎn)的位置的,? 實(shí)際上就是遍歷以Jason 為跟節(jié)點(diǎn)的字樹啊. 看輸出結(jié)果, 明顯是1個(gè)先序遍歷行為.? 至于樹的遍歷知識(shí)可以參考我的博文中的數(shù)據(jù)結(jié)構(gòu)部分.

4) 如果只想得出Jason的所有子孫節(jié)點(diǎn), 不需要把Jason本身也select出來, 可以在 start with字句上面加上 where id <>2 子句.



3.4 查找某個(gè)節(jié)點(diǎn)的所有祖輩

例如我想找出Bill的所有直接和間接的上司(上司的上司).

Oracle 中 connect by字句同樣可以方便的實(shí)現(xiàn)這個(gè)功能,

關(guān)鍵就是prior 的位置要在parent id前面


語句如下:

select * from tree_1 start with id = 7 --Bill's id connect by id = prior p_id;
留意 prior 關(guān)鍵字的位置啊.


輸出:

ID NAME P_ID ---------- -------------------- ----------7 Bill 55 Peter 22 Jason 11 Nedved 0


總結(jié)

以上是生活随笔為你收集整理的Oracle connet by prior 关键字的简单介绍和用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。