oracle 数据库中 connect by 和level 的用法
?這幾天看sql看到了有關connect by和level的關鍵字用法,以前都用mysql也沒用過這個關鍵字,感覺挺有用的,就學了下,整理一下學習過程。
??????首先,connect by和level都是為了快速的查詢層級關系的關鍵字,在代理關系中,或者權限關系中,經常會有層層嵌套的場景,比如,同行數據的第一個字段是ID,第二個字段是parentID,parentID表示他的上級ID是誰。
???????如一條數據,ID為1,parentID為0,表示沒有上級,即頂層,grade 為老板
???????第二條數據,ID為2,parentID為1,表示上級為1,grade 為總監
????????第三條數據,ID為3,parentID為2,表示上級為2,grade 為經理
????????這就是一個三級的層級關系事例。
??????在這種情況下,如果想知道某個:比如 一級代理的所有二級代理和三級代理的有關行是誰,就很麻煩了。如果使用mysql數據庫,就有兩種方法
MYSQL
???????第一種是在java代碼或者別的service層,或工具層中編寫有關層級關系解析的方法代碼,然后把解析的數據放在redis或者map中(如果不放在redis 或者map中,數據量大的時候,每次調用關系都要重新算一遍是很大的消耗)。
???????第二種是在mysql數據庫中編寫相對的存儲過程,在select 查詢的時候調用自己封裝好的方法,獲取相應的數據庫信息。
???但是oracle 中,則很貼心的提供了對應的方法來解決上述的問題,這就是關鍵字:connect by?
????????其實簡單來說,其基本語法是????
???select …,level from tablename???????start with 條件1connect by???prior 子字段id=父字段idwhere 條件3;???????例子:
??????SELECT a.FUNCID,a.PARENTID,LEVEL FROM AUTH_FUNC a START WITH a.FUNCID=3173
??????CONNECT BY PRIOR ?a.FUNCID = a.PARENTID;
?????????以上述模板為例,LEVEL是查詢的層級,START WITH a.FUNCID=3173,表示從該條件開始尋找層級關系,CONNECT BY PRIOR a.FUNCID=a.PARENTID 代表,優先按照a.FUNCID當做基礎,該例中(PARENTID的值,綁定的是FUNCID),所以查找FUNCID=3173的所有兒子孫子,及其層級(兒子LEVEL是2,孫子LEVEL是3)【即查詢所有的兒子孫子等等】
范例一:優先查詢3174(父節點)的所有孩子
?????????如果變成CONNECT BY a.FUNCID= PRIOR a.PARENTID,則代表起始為a.FUNCID=3173,優先按照PARENTID查找,即尋找FUNCID=3173這條數據的所有父節點行。【查詢所有的父節點】
范例二:優先查詢3174(子節點)所有父節點
??????????這里有點難以理解,但是其實就是如果,PRIOR 放在父字段端,就是尋找STRAT WITH 標注節點的所有的子節點,如果PRIOR 放在子字段端,就是尋找STRAT WITH 標注節點的所有的父節點
??????????????因為一個兒子只有一個父親,而一個父親可能有多個兒子,所以當PRIOR放在父字段端的時候,可能有多個層級族,因為在找兒子。當放在子字段端的時候,最多只會有一個層級族,因為,他在找爸爸。
???????關于?connect by 和level 還有startwith 的詳細介紹和延伸,我在學習過程中,找到了兩個很好的博客,在此就不轉載了,直接轉網址了,以供以后自己學習和看此篇博客的人學習。
???????oracle connect by用法篇:https://blog.csdn.net/wang_yunj/article/details/51040029/
???????Oracle中start with...connect by子句的用法:http://www.blogjava.net/xzclog/archive/2010/03/05/314642.html
????????看完這兩篇博客,應該是能懂很多東西的,我這里在嘗試和學習的過程中,也做了一些事例,如果在有oracle數據庫,且想很快形象的學習有關這塊知識,也可以直接在oracle中執行我的事例代碼,配上注釋,應該能簡單不少。
?????????后續如果有更多的相關知識,會在加在下面的
??????????事例代碼
?????????
--關于LEVEL,START WITH CONNECT BY 的例子
--創建數據庫實例 CREATE TABLE "CHANNEL"."AUTH_FUNC" ( "FUNCID" VARCHAR2(255) NOT NULL , "PARENTID" VARCHAR2(255) NOT NULL , PRIMARY KEY ("FUNCID") ) NOCOMPRESS ;?
INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3173', '0'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3174', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3175', '3174'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3176', '3174'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3177', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3178', '3177'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3179', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3180', '3179'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3181', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3182', '3181'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3183', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3184', '3183'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3185', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3186', '3173'); INSERT INTO "AUTH_FUNC" ("FUNCID", "PARENTID") VALUES ('3187', '3173'); select * from AUTH_FUNC order by parentid;
?
--輸出從1到100
?
--輸出所有數據,這個時候,因為沒有在條件中設置層級關系,所以LEVEL為多大都不影響結果
--輸出所有數據,這個時候,因為沒有在條件中設置層級關系,所以LEVEL為多大都不影響結果
--但是此條中將LEVEL加入了WHERE條件,所以查詢結果受影響
?
--以上語句只是為了方便理解LEVEL,他其實就是一個可以當做條件的,
--限制或表現層數的方法字段
?
?
--接下來是CONNECT BY的用法
--想找到父節點是0開始的所有相關子節點及其層數
--也就是FUNCID 為3173的所有子節點(從父節點從父級,從上往下查找,可能獲得多個子集分支)
?
--將PRIOR 放在等于號后面,將會獲得不同的結果(從子節點開始查詢,獲取上層節點)
--因為該處FUNCID 就為頂級,作為子節點查詢的話,肯定只有一條
--原因就是,PRIOR是優先級的意思,放在前面或者后面,或者調換等于號兩遍的條件順序都會獲得相反的結果
?
?
--如這個例子,就表示了以FUNCID 3175開始,從子節點遍歷獲取上層節點的例子
--因為是從子節點開始所以,節點族肯定只有一條,即:一個孫子只有一個爺爺
?
--如這個例子,就表示了以FUNCID 3174開始,從父節點遍歷獲取下層子節點的例子
--因為是從父節點開始所以,節點族可能有多條,即:一個爺爺可能有多個兒子和孫子
?
--省略了START WITH 則表示全部滿足查詢條件的行,作為根節點
?
總結
以上是生活随笔為你收集整理的oracle 数据库中 connect by 和level 的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: InnoDB ReplicaSet
- 下一篇: 几款主流好用的富文本编辑器(所见即所得常