ORACLE中樹的各種查詢方法

2021-10-07 11:37:19 字數 3998 閱讀 6382

注:以下sql可以在開發庫的zk_component中執行。

1.查詢乙個節點的所有 直屬子節點(所有後代)。

sql**

select * from zk_tree start with depid = 『08130006』 connect by parentdepid = prior depid order siblings by sortby

ps:order siblings by sortby:每層節點資料的排序。

這個查詢的是id為』08130006』 的節點下的所有直屬子類節點,包括子輩的和孫子輩的所有直屬節點。

2.查詢乙個節點的所有直屬父節點(祖宗)。

sql**

select * from zk_tree start with depid = 『08130006』 connect by prior parentdepid = depid order siblings by sortby

這裡查詢的就是id為』08130006』 的所有直屬父節點,打個比方就是找到乙個人的父親、祖父等。但是值得注意的是這個查詢出來的結果的順序是先列出子類節點再列出父類節點。

上面列出兩個樹型查詢方式,這兩條語句之間的區別在於prior關鍵字的位置不同,所以決定了查詢的方式不同。 當parentdepid = prior depid 時,資料庫會根據當前的id迭代出parentdepid與該depid相同的記錄,所以查詢的結果是迭代出了所有的子類記錄;而prior parentdepid = depid 時,資料庫會跟據當前的parentdepid 來迭代出與當前的parentdepid 相同的depid 的記錄,所以查詢出來的結果就是所有的父類結果。

以下是一系列針對樹結構的更深層次的查詢,這裡的查詢不一定是最優的查詢方式,或許只是其中的一種實現而已。

3.查詢與乙個節點同級的節點(族兄弟)。

如果在表中設定了級別的字段,那麼在做這類查詢時會很輕鬆,同一級別的就是與那個節點同級的,在這裡列出不使用該字段時的實現!

sql**

with tmp as

(select a.*, level lev

from zk_tree a

start with a.parentdepid is null

connect by a.parentdepid = prior a.depid)

select *

from tmp

where lev = (select lev

from tmp

where depid = 『08130006』)

這裡使用兩個技巧,乙個是使用了level來標識每個節點在表中的級別,還有就是使用with語法模擬出了一張帶有級別的臨時表。

4.查詢乙個節點的父節點的的兄弟節點(伯父與叔父)。

sql** (1)

with tmp as

(select a., level lev

from zk_tree a

start with parentdepid is null

connect by parentdepid = prior depid)

select b.

from tmp b,

(select *

from tmp

where depid = 『08130006』 and lev = 2)

where b.lev = 1

union all

select *

from tmp

where parentdepid =

(select distinct x.depid

from tmp x,

tmp y,

(select *

from tmp

where depid = 『08130006』 and lev > 2) z

where y.depid = z.parentdepid

and x.depid = y.parentdepid)

這裡查詢分成以下幾步。首先,將第3個一樣,將全表都使用臨時表加上級別;其次,根據級別來判斷有幾種型別,以上文中舉的例子來說,有三種情況:

(1)當前節點為頂級節點,即查詢出來的lev值為1,那麼它沒有上級節點,不予考慮。

(2)當前節點為2級節點,查詢出來的lev值為2,那麼就只要保證lev級別為1的就是其上級節點的兄弟節點。

(3)其它情況就是3以及以上級別,那麼就要選查詢出來其上級的上級節點(祖父),再來判斷祖父的下級節點都是屬於該節點的上級節點的兄弟節點。 最後,就是使用union將查詢出來的結果進行結合起來,形成結果集。

sql** (2)

with tmp as

(select a.*, level lev

from flfl a

start with a.sjflid is null

connect by a.sjflid = prior a.id)

select *

from tmp

where lev = (select lev

from tmp

where id = 819394) - 1

ps:該方法得到的結果和上方sql一樣。

5.名稱要列出名稱全部路徑。

這裡常見的有兩種情況,一種是是從頂級列出,直到當前節點的名稱(或者其它屬性);一種是從當前節點列出,直到頂級節點的名稱(或其它屬性)。舉位址為例:國內的習慣是從省開始、到市、到縣、到居委會的。

從頂部開始:

sql**

select a.*, sys_connect_by_path (depname, 『/』)

from zk_tree a

connect by prior a.depid = a.parentdepid

start with a.parentdepid is null

order siblings by sortby

從當前節點開始:

sql**

select a., sys_connect_by_path (depname, 『/』)

from zk_tree a

start with depid =『08130006』

connect by prior parentdepid = depid

sys_connect_by_path函式就是從start with開始的地方開始遍歷,並記下其遍歷到的節點,start with開始的地方被視為根節點,將遍歷到的路徑根據函式中的分隔符,組成乙個新的字串,這個功能還是很強大的。

6.列出當前節點的根節點。

在前面說過,根節點就是start with開始的地方。

sql** (1)

select a., connect_by_root depname

from zk_tree a

start with depid =『08130006』

connect by prior parentdepid = depid

sql** (2)

列出所有節點的根節點

select a.*, connect_by_root depname

from zk_tree a

start with parentdepid is null

connect by parentdepid = prior depid

connect_by_root函式用來列的前面,記錄的是當前節點的根節點的內容。
7.列出當前節點是否為葉子。

這個比較常見,尤其在動態目錄中,在查出的內容是否還有下級節點時,這個函式是很適用的。

sql**

select a.*, connect_by_isleaf

from zk_tree a

start with parentdepid is null

connect by parentdepid = prior depid

connect_by_isleaf函式用來判斷當前節點是否包含下級節點,如果包含的話,說明不是葉子節點,這裡返回0;反之,如果不包含下級節點,這裡返回1。

Oracle各種時間查詢

1.獲取時間的日 select to char sysdate,dd as nowday from dual 2.獲取時間的時 select to char sysdate,hh24 as nowhour from dual 3.獲取時間的分 select to char sysdate,mi as...

Unity中各種查詢物體方法的區別

通過名字或者路徑查詢遊戲物件 使用規範 1 無法查詢隱藏物件 隱藏物件包括查詢路徑的任何乙個父節點隱藏 2 如果查詢不再最上層,建議合理使用路徑查詢,路徑查詢是把雙刃劍 優點1 解決查詢中可能出現的重名問題。優點2 如果有完全的路徑,減少查詢範圍,減少查詢時間 缺點 路徑或者結構調整後,很容易影響到...

各種模組方法查詢

在python中乙個.py檔案稱之為乙個模組 按照功能將 加以區分,可以用import去呼叫模組 自定義模組名字要避免與內建模組重名 模組的安裝 easy install pycharm內setting安裝 pip 官方推薦 模組入口 只能在當前檔案執行 if name main fuinc os模...