在db2和oracle中的對樹的遞歸查詢語句。
表結構:
create table? MAIN_NODE (
MLA_ID????? ?????????INTEGER???? not null??????? ,?? //節點ID
MLA_ROOTID????????? INTEGER,?? ???????????????????//根節點ID
MLA_PARENTID??????? INTEGER,??? ??????????????????//父節點ID
MLA_NAME??????????? VARCHAR2(50), ???????????????//節點名稱
constraint P_mlaid primary key (MLA_ID) );
MLA_ID ??MLA_PARENTID ?MLA_ROOTID?? MLA_NAME
1? ???????? 0??? ??????????? ???0??? ?????????父節點1?????
2? ???????? 1??? ??????????? ???0??? ????????(父節點1的/)子節點1???
3?????? ??? ?2??? ???????????? ??0?? ?????????(父節點1的/子節點1的/)孫子節點1
4? ???????? 0??? ??????????? ???0??? ?????????父節點2?????
5? ???????? 4??? ?????????? ????0???? ???????(父節點2的/)子節點1???
樹結構直觀圖:
根節點(0)
???? 父節點1(1)
?????????? (父節點1的/)子節點1(2)?
???????????????????? (父節點1的/子節點1的/)孫子節點1(3)
???? 父節點2(4)
?????????? (父節點2的/)子節點1(5)
語句要求的功能:實現給出一個父節點id然后得到該父節點下的所有子節點的信息Db2 的查詢語句:
WITH ?RPL (mla_parentid, mla_id, mla_name) AS
(
SELECT ROOT.mla_parentid, ROOT.mla_id, ROOT.mla_name FROM main_node ROOT WHERE ROOT.mla_id = ?
UNION ?ALL
SELECT
CHILD.mla_parentid, CHILD.mla_id, CHILD.mla_name FROM RPL PARENT,
main_node CHILD WHERE PARENT.mla_parentid = CHILD.mla_id
?)
SELECT DISTINCT mla_parentid, mla_id, mla_name FROM RPL ORDER BY mla_parentid, mla_id, mla_name
讓我們研究這個查詢語句:
- RPL 作為一個具有以下三列的虛擬表:mla_parentid, mla_id 和 mla_name。
- WITH 子句內的第一個 SELECT 語句是初始化表。它只執行一次。它的結果形成虛擬表的初始內容以作為遞歸的種子。在上面的示例中,種子是 mla_id 為 任意傳進去的參數 的一行或多行。
- 第
二個 SELECT 語句執行多次。將種子作為輸入(JOIN 中的輔助表)傳遞給第二個 SELECT 語句以產生下一個行集合。將 JOIN
的結果添加(UNION ALL)到虛擬表的當前內容中,并放回到其中以形成用于下一次傳遞的輸入。只要有行產生,這個過程就會繼續。
- 如果期望,虛擬表上最后的 SELECT 允許我們選擇遞歸查詢所產生的所有行或僅部分行。
Oracle的查詢語句:
?? select mla_parentid, mla_id, mla_name from main_node
start with mla_id=? connect by prior mla_id=mla_parentid
讓我們研究這個查詢語句:
- ? 本語句實際上是 start with ...connect by 的用法, start with 后面所跟的就是就是遞歸的種子。在上面的示例中,種子是 mla_id 為 任意傳進去的參數
- connect by 后面的"prior"如果缺省:則只能查詢到符合條件的起始行,并不進行遞歸查詢;
- connect by prior 后面所放的字段是有關系的,它指明了查詢的方向。如果后面放的是 mla_id=mla_parentid 則表明從本節點查向葉子節點;如果后面放的是 mla_parentid = mla_id則表明從根節點查向本節點;