如何理解樹狀sql中ORDER SIBLINGS BY排序的含義

warehouse發表於2011-10-19

SIBLINGS 是兄弟姐妹的意思,那麼ORDER SIBLINGS BY的意思就是在兄弟姐妹之間的排序,和order by所表示的含義絕對不同,針對樹狀sql,我覺得ORDER SIBLINGS BY更有意義,樹狀sql查詢出來的結果本身就是按照層次(hierarchy)結構排好序的,而加上關鍵字SIBLINGS 其實是在hierarchy內部進行排序。

[@more@]

You have to be careful when trying to order the rows of output in a hierarchical
query. By default, if you omit the ORDER BY clause altogether, the query attempts
to sort rows in an order that’s reflective of the hierarchy. Display will start first with
a LEVEL 1 row. If that row is superior to any LEVEL 2 rows, those rows will display
next before another LEVEL 1 row displays. The same approach is taken at LEVEL
2, so that rows will display down to leaf node levels before the next rows show at
the higher levels. The result is a display that is meaningful to the hierarchy. But if
you try to order these rows with the ORDER BY clause, you’ll create a syntactically
correct statement that probably doesn’t help you much

--===================================

上面是047教材中對ORDER SIBLINGS BY的描述,看的有點暈,下面看一個例子來理解一下SIBLINGS吧:

SQL> select * from t_tree_query;

NAME MID ID
---------- ---------- ----------
level999 0 1
level2 1 2
level3 2 3
level4 3 4
level5 4 5
level6_7 5 6
level6_6 5 7
level5 4 8
level6 8 9
level4 3 10
level5_12 10 11

NAME MID ID
---------- ---------- ----------
level5_11 10 12
level6 12 13

13 rows selected.

SQL>

表t_tree_query裡的資料如上,欄位mid是id的parent,name看成是id對應的名字,下面是一個樹狀sql的查詢結果,目的是求mid=0也就是父親id=0的所有孩子id的關係:

SQL> select name,level,mid,id ,lpad(' ',level*2)||id level_id,SYS_CONNECT_BY_PATH(id,'/') path
2 ,CONNECT_BY_ROOT id root_id
3 from t_tree_query
4 start with mid in (0)
5 connect by prior id = mid
6 ;

NAME LEVEL MID ID LEVEL_ID PATH ROOT_ID
---------- ---------- ---------- ---------- -------------------- --------------- ----------
level999 1 0 1 1 /1 1
level2 2 1 2 2 /1/2 1
level3 3 2 3 3 /1/2/3 1
level4 4 3 4 4 /1/2/3/4 1
level5 5 4 5 5 /1/2/3/4/5 1
level6_7 6 5 6 6 /1/2/3/4/5/6 1
level6_6 6 5 7 7 /1/2/3/4/5/7 1
level5 5 4 8 8 /1/2/3/4/8 1
level6 6 8 9 9 /1/2/3/4/8/9 1
level4 4 3 10 10 /1/2/3/10 1
level5_12 5 10 11 11 /1/2/3/10/11 1

NAME LEVEL MID ID LEVEL_ID PATH ROOT_ID
---------- ---------- ---------- ---------- -------------------- --------------- ----------
level5_11 5 10 12 12 /1/2/3/10/12 1
level6 6 12 13 13 /1/2/3/10/12/13 1

13 rows selected.

SQL>

查詢的結果是按照mid和id的層次關係排好了序,但是我們希望在具有相同父親的孩子之間按照name來排序,這樣加上order siblings by name子句的查詢結果如下:

SQL> select name,level,mid,id ,lpad(' ',level*2)||id level_id,SYS_CONNECT_BY_PATH(id,'/') path
2 ,CONNECT_BY_ROOT id root_id
3 from t_tree_query
4 start with mid in (0)
5 connect by prior id = mid
6 order siblings by name
7 ;

NAME LEVEL MID ID LEVEL_ID PATH ROOT_ID
---------- ---------- ---------- ---------- -------------------- --------------- ----------
level999 1 0 1 1 /1 1
level2 2 1 2 2 /1/2 1
level3 3 2 3 3 /1/2/3 1
level4 4 3 4 4 /1/2/3/4 1
level5 5 4 5 5 /1/2/3/4/5 1
level6_6 6 5 7 7 /1/2/3/4/5/7 1
level6_7 6 5 6 6 /1/2/3/4/5/6 1
level5 5 4 8 8 /1/2/3/4/8 1
level6 6 8 9 9 /1/2/3/4/8/9 1
level4 4 3 10 10 /1/2/3/10 1
level5_11 5 10 12 12 /1/2/3/10/12 1

NAME LEVEL MID ID LEVEL_ID PATH ROOT_ID
---------- ---------- ---------- ---------- -------------------- --------------- ----------
level6 6 12 13 13 /1/2/3/10/12/13 1
level5_12 5 10 11 11 /1/2/3/10/11 1

13 rows selected.

SQL>

觀查一下name中level6_6和level6_7的位置發現他們的順序發生了變化,他們的父親都是mid=5,在不加order siblings by name之前,id=6在id=7之前,按照name排序之後,發現id=7在id=6前面了,大家也可以觀查mid=10時id=11,12,13時的變化,發現加上siblings 之後父親12會帶著孩子13同時和11的順序顛倒了。

注意siblings 的作用僅僅是兄弟姐妹之間的排序,不管加上siblings 與否,level999的位置始終是在第一位的。

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

相關文章