select a.*, level from dlsys.tcUnit a where nvl(validFlag,1) = 1
start with SeniorUnitId is null connect by SeniorUnitID = prior UnitID
order siblings by DisplayOrder
Oracle中的select語句能夠用start with ... connect by prior ...子句實現遞歸查詢,connect by 是結構化查詢中用到的,其基本語法是: sql
select ... from
where <過濾條件,用於對返回的全部記錄進行過濾>
start with <根結點的限定語句,固然能夠放寬限定條件,以取得多個根結點,實際就是多棵樹>
connect by [prior] <鏈接條件,其中用prior表示上一條記錄,好比:connect by prior t.id = t.parent_id就是說上一條記錄的id 是本條記錄的parent_id,即本記錄的父親是上一條記錄>
下面咱們直接來看實例,查詢'KING'的全部下屬僱員。SQL語句以下:
- select *
- from scott.emp e
- start with e.ename = 'KING'
- connect by prior e.empno = e.mgr;
咱們再來看另一個實例,反過來查詢'SMITH'的全部上司。SQL語句以下:
- select *
- from scott.emp e
- start with e.ename = 'SMITH'
- connect by e.empno = prior e.mgr;
經過上面的兩個實例,估計你們應該理解的差很少了,接下來介紹connect by的幾個固定搭檔。
一、sys_connect_by_path函數
語法:sys_connect_by_path(列名, '分隔符')。
做用:從start with的地方開始遍歷,將遍歷到的路徑根據函數中的分隔符,組成一個新的字符串。 函數
- select sys_connect_by_path(ename, '/') ename_tree
- from scott.emp
- start with ename = 'KING'
- connect by mgr = prior empno;
插個題外話,介紹sys_connect_by_path函數使用的一個小技巧,把查詢行轉換成列,把表emp的全部列名以'|'分隔開輸出(提示:你們能夠把下面的語句拆開來逐個分析),SQL語句以下:
- select max(ltrim(sys_connect_by_path(column_name, '|'), '|')) column_names
- from (select column_name, rownum rnum
- from user_tab_columns
- where table_name = 'EMP')
- start with rnum = 1
- connect by rnum = rownum;
二、level:在結構化查詢結果中,每一行都是結構中的一個節點,level表示該節點在結構中的層次,根節點爲1,根節點的子節點爲2,以此類推。
下面SQL語句很直觀的展現效果: spa
- select ename, sys_connect_by_path(ename, '/') ename_tree, level
- from scott.emp
- start with ename = 'KING'
- connect by mgr = prior empno;
三、connect_by_root:用在列名以前,返回當前節點的根節點對應列的值。connect_by_isleaf:返回當前節點是否爲葉子節點,「是」返回1,「否」返回0。
下面SQL語句很直觀的展現效果: .net
- select sys_connect_by_path(ename, '/') ename_tree,
- connect_by_root ename as root,
- connect_by_isleaf as isleaf
- from scott.emp e
- start with e.ename = 'KING'
- connect by prior e.empno = e.mgr;