<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    CONAN ZONE

    你越掙扎我就越興奮

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
    轉自:http://www.javaeye.com/topic/625574

    有的情況下,我們需要用遞歸的方法整理數據,這才程序中很容易做到,但是在數據庫中,用SQL語句怎么實現?下面我以最典型的樹形結構來說明下如何在Oracle使用遞歸查詢。
        為了說明方便,創建一張數據庫表,用于存儲一個簡單的樹形結構
    Sql代碼
    1. create table TEST_TREE  
    2. (  
    3.   ID   NUMBER,  
    4.   PID  NUMBER,  
    5.   IND  NUMBER,  
    6.   NAME VARCHAR2(32)  
    7. )  


        ID是主鍵,PID是父節點ID,IND是排序字段,NAME是節點名稱。初始化幾條測試數據。

    ID PID IND NAME
    1 0 1 根節點
    2 1 1 一級菜單1
    3 1 2 一級菜單2
    4 1 2 一級菜單3
    5 2 1 一級1子1
    6 2 2 一級1子2
    7 4 1 一級3子1
    8 4 2 一級3子2
    9 4 3 一級3子3
    10 4 0 一級3子0

    一、基本使用:

        在Oracle中,遞歸查詢要用到start   with 。。。。connect   by   prior。。。

        具體格式是:

    Sql代碼
    1. SELECT column  
    2. FROM table_name  
    3. START WITH column=value  
    4. CONNECT BY PRIOR 父主鍵=子外鍵  

        對于本例來說,就是:

    Sql代碼
    1. select   d.*   from  test_tree d   
    2.   start   with   d.pid=0  
    3.   connect   by   prior   d.id=d.pid   

       查詢結果如下:

    ID PID IND NAME
    1 0 1 根節點
    2 1 1 一級菜單1
    5 2 1 一級1子1
    6 2 2 一級1子2
    3 1 2 一級菜單2
    4 1 2 一級菜單3
    7 4 1 一級3子1
    8 4 2 一級3子2
    9 4 3 一級3子3
    10 4 0 一級3子0

     我們從結果中可以看到,記錄已經是按照樹形結構進行排列了,但是現在有個新問題,如果我們有這樣的需求,就是不但要求結果按照樹形結構顯示,還要根據ind字段在每一個分支內進行排序,這個問題怎么處理呢?我們可能很自然的想到如下語句:

    Sql代碼
    1. select   d.*   from  test_tree d   
    2.   start   with   d.pid=0  
    3.   connect   by   prior   d.id=d.pid   
    4.   order by d.ind  

     結果如下:

    ID PID IND NAME
    1 0 1 根節點
    2 1 1 一級菜單1
    5 2 1 一級1子1
    6 2 2 一級1子2
    4 1 2 一級菜單3
    10 4 0 一級3子0
    8 4 2 一級3子2
    9 4 3 一級3子3
    7 4 1 一級3子1
    3 1 2 一級菜單2

    這顯然不是我們想要的結果,那下面的這個語句呢?

    Sql代碼
    1. select   d.*   from  (select dd.* from test_tree dd order by dd.ind) d   
    2.   start   with   d.pid=0  
    3.   connect   by   prior   d.id=d.pid   

    結果如下:

    ID PID IND NAME
    1 0 1 根節點
    2 1 1 一級菜單1
    5 2 1 一級1子1
    6 2 2 一級1子2
    4 1 2 一級菜單3
    10 4 0 一級3子0
    8 4 2 一級3子2
    9 4 3 一級3子3
    7 4 1 一級3子1
    3 1 2 一級菜單2

    這個結果看似對了,但由于一級菜單3節點下有一個節點的ind=0,導致一級菜單2被拍到了3下面。如果想使用類似這樣的語句做到各分支內排序,則需要找到一個能夠準確描述菜單級別的字段,但是對于示例表來說,不存在這么一個字段。

    那我們如何實現需求呢?其實Oracle9以后,提供了一種排序“order siblings by”就可以實現我們的需求,用法如下:

    Sql代碼
    1. select   d.*   from  test_tree d   
    2.   start   with   d.pid=0  
    3.   connect   by   prior   d.id=d.pid   
    4.   order   siblings   by   d.ind   asc  

    結果如下:

    ID PID IND NAME
    1 0 1 根節點
    2 1 1 一級菜單1
    5 2 1 一級1子1
    6 2 2 一級1子2
    3 1 2 一級菜單2
    4 1 2 一級菜單3
    10 4 0 一級3子0
    7 4 1 一級3子1
    8 4 2 一級3子2
    9 4 3 一級3子3

    這樣一來,查詢結果就完全符合我們的要求了。

    至于在Oracle8以前版本,或者其他數據庫中如何實現類似的功能,希望大家來指教下,謝謝。



    posted on 2010-04-12 13:35 CONAN 閱讀(321) 評論(0)  編輯  收藏 所屬分類: SQLOracle
    主站蜘蛛池模板: 久久九九亚洲精品| 中文字幕亚洲激情| 亚洲乱码一二三四区麻豆| 99热这里只有精品免费播放| 亚洲第一AV网站| 久操免费在线观看| 亚洲黄色免费网站| 亚洲国产成人精品无码区在线观看 | 久久久久久久久无码精品亚洲日韩| 色婷婷综合缴情综免费观看| 好爽好紧好大的免费视频国产| 亚洲精品乱码久久久久久V | 亚洲精品无码久久久久sm| 中文精品人人永久免费| 久久精品国产亚洲av日韩| 中文字幕免费观看| 亚洲综合国产成人丁香五月激情| a级大片免费观看| 亚洲国产人成网站在线电影动漫 | 国产亚洲?V无码?V男人的天堂| 国产高清视频免费在线观看| 大陆一级毛片免费视频观看i| 亚洲AV无码片一区二区三区| 亚洲AV无码乱码在线观看性色扶| 精品多毛少妇人妻AV免费久久| 久久精品国产96精品亚洲| 青娱乐在线视频免费观看| 成人最新午夜免费视频| 亚洲视频精品在线观看| 成年人在线免费观看| 日韩在线观看免费| 亚洲伦理一区二区| 国产色爽免费视频| 亚洲精品成a人在线观看夫| 亚洲成AV人网址| 亚洲一区免费在线观看| 亚洲va久久久噜噜噜久久狠狠| 99久久99久久精品免费看蜜桃| 亚洲高清在线观看| 成人免费毛片视频| 少妇人妻偷人精品免费视频|