【層次查詢】Hierarchical Queries之“樹的遍歷”

secooler發表於2009-12-28
在介紹層次查詢的過程中,我們將會反覆使用到下面這棵“樹”,雖然它看上去只是一棵很普通的樹,但其中蘊含著很多值得探索的內容。

      A
     / \
    B   C
   /   /
  D   E
 / \
F   G

1.“樹”的自述
A:我是B和C的父親
B:我是A的兒子,是D的父親,是C的親兄弟
C:我是A的兒子,是E的父親,是B的
兄弟
D:我是B的兒子,是F和G的父親
E:我是C的兒子
F:我是D的兒子,是G的
兄弟
G:我是D的兒子,是F的
兄弟

2.透過自關聯表T構造上述那棵“樹”
sec@ora10g> create table t (x varchar2(10),y number,z number);
sec@ora10g> alter table t add constraint pk_t primary key (y);
sec@ora10g> alter table t add constraint fk_t foreign key (z) references t (y);
sec@ora10g> insert into t values ('A',1,null);
sec@ora10g> insert into t values ('B',2,1);
sec@ora10g> insert into t values ('C',3,1);
sec@ora10g> insert into t values ('D',4,2);
sec@ora10g> insert into t values ('E',5,3);
sec@ora10g> insert into t values ('F',6,4);
sec@ora10g> insert into t values ('G',7,4);
sec@ora10g> commit;

3.表T的內容
sec@ora10g> select * from t;

X                   Y          Z
---------- ---------- ----------
A                   1
B                   2          1
C                   3          1
D                   4          2
E                   5          3
F                   6          4
G                   7          4

7 rows selected.

仔細將這個表和上面的樹做個比對,顯然,它們是等價的。
T表體現的是一種層級關係,可以想象z列內容記錄的是該行記錄的父親結點資訊。

4.使用層次查詢“遍歷”這棵樹。
使用最簡單的connect by語句便可完成對整個樹的全面遍歷,如果您是第一次使用這樣的高階SQL語句,請不要暈,因為沒有做更多的限制,結果可能貌似有點亂,不過可以靜下心來仔細研究一番,便可頓開茅塞。
sec@ora10g> select x, y, z from t connect by prior y=z;

X                   Y          Z
---------- ---------- ----------

B                   2          1
D                   4          2
F                   6          4
G                   7          4
C                   3          1
E                   5          3
D                   4          2
F                   6          4
G                   7          4
E                   5          3
F                   6          4
G                   7          4
A                   1
B                   2          1
D                   4          2
F                   6          4
G                   7          4
C                   3          1
E                   5          3

19 rows selected.

5.請按照我標註的顏色,分組檢視上面的內容
紅色的4行資料(B、D、F、G):表示結點A左側的整棵子樹;
藍色的2行資料(C、E):表示結點A右側的整棵子樹;
橙色的3行資料(D、F、G):表示結點B左側的整棵子樹;
綠色的E:葉子結點;
棕色的F:葉子結點;
淺藍的G:葉子結點;
紫色的7行資料(A、B、D、F、G、C、E):表示整棵樹。

透過上面的解釋,您應該對自關聯的表的層次查詢有了一個感性的認識。

6.只得到以結點“A”為根的樹
也就是隻想得到上面紫色的7條資料,因為其他資料對於我來說是一種沒有必要的重複。
此時我們僅需要使用層次查詢中的start with子句便可。
sec@ora10g> select x, y, z from t start with x = 'A' connect by prior y=z;

X                   Y          Z
---------- ---------- ----------
A                   1
B                   2          1
D                   4          2
F                   6          4
G                   7          4
C                   3          1
E                   5          3

7 rows selected.

這裡使用“start with x = 'A'”子句可以限制只選取以結點“A”為根的樹。

7.小結
使用層次查詢可以非常便捷的得到自關聯表的內在邏輯聯絡,這是Oracle的一個特色功能,將繁瑣的功能化解到了一條SQL之中。

Good luck.

secooler
09.12.28

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-623809/,如需轉載,請註明出處,否則將追究法律責任。

相關文章