oracle中connect by 神奇的用法

? ? 在code的過程中曾經(jīng)遇到過一個神奇的問題:

? ? 現(xiàn)在有多條火車線路,經(jīng)過了若干站點,找出經(jīng)過P站點能直接到達的所有站點。

? ? 其中在數(shù)據(jù)庫中存儲的線路是分路段存儲,格式是? ID? ?A_STATION? Z_STATION? 其他屬性略,比如? ? ?a->b->c->d->e->f->g 那么存儲的數(shù)據(jù) 為??

? ? ? ? 1? ?a? ? b

? ? ? ? 2? ?c? ? b

? ? ? ? 3? ? c? ? d

? ? ? ? ...

? ? 看出來了,分路段存儲,但是又無序,不是嚴格按照? a->b , b->c , c->d 這樣存儲的,剛開始的時候,我也沒有想過其他方法,直接在代碼中使用了遞歸來判斷,循環(huán)查詢數(shù)據(jù),但是發(fā)現(xiàn)這樣效率并不高,而且遞歸的過程中很容易出錯,這時候,我發(fā)現(xiàn)oracle中有一個connect by實現(xiàn)的遞歸查詢,于是打算使用一下。

? ? 使用過程中發(fā)現(xiàn)由于數(shù)據(jù)不是嚴格的有序排序,A,Z無序,無法直接使用,這時,我動了一個歪腦筋,由于表中數(shù)據(jù)量也不是太大,只有幾萬條記錄,我能不能把表中所有數(shù)據(jù)翻轉(zhuǎn)一下,A,Z 變成 Z,A然后重命名為 A,Z,再使用union 拼接成兩倍記錄的新表,想到之后馬上就做,于是有了:

? ?? (select id,a_id,z_id

? ? ? ? ? ?from table

? ? ? ? ? ? ?union

? ? ? ? ? ? select id,z_id as a_id,a_id as z_id

? ? ? ? ? ?from table) t

? ? 這是一張新的表,里面的記錄是原表的兩倍,然后對這個表進行connect by 遞歸查詢:

? ??????select *

? from (select id, a_id, z_id

? ? ? ? ? from table

? ? ? ? union

? ? ? ? select id, z_id as a_id, a_id as z_id

? ? ? ? ? from table) t

start with t.a_id = ?

connect by? prior t.z_id = t.a_id

? ? 哈哈,這下好了吧,解決了無序的問題??墒切碌膯栴}出現(xiàn)了,我一運行,沒有報錯,可是數(shù)據(jù)怎么有問題。重復(fù)了兩次?仔細一想,數(shù)據(jù)重復(fù)了兩次,這樣不但查詢出來的結(jié)果會有問題,而且說不定還會報無限遞歸調(diào)用的錯誤(可能是我使用的ID正好,所有偶然的沒有報錯,不然會無限遞歸報錯)。這個怎么解決呢?

? ? 然后我查詢了一下網(wǎng)上oracle 的 connect by 使用的很多案例,發(fā)現(xiàn)了oracle的一個關(guān)鍵字“NOCYCLE”,還有嵌套使用的一個條件“connect_by_iscycle = 0”,限制了遞歸過程中不能成環(huán),然后再加上我自己生成的數(shù)據(jù)跟原始數(shù)據(jù)的id是相同的,那么我可以限制id只能出現(xiàn)一次,不能重復(fù)使用一條記錄遞歸“t.id <> t.id”經(jīng)過修改,最終的SQL成了下面這樣:

select *

? from (select id, a_id, z_id

? ? ? ? ? from table

? ? ? ? union

? ? ? ? select id, z_id as a_id, a_id as z_id

? ? ? ? ? from table) t

where connect_by_iscycle = 0

start with t.a_id = ?

connect by NOCYCLE prior t.z_id = t.a_id

? ? ? and prior t.id <> t.id

? ? 最終實現(xiàn)了需求,當然,我這樣使用在很多時候是不合規(guī)的,有什么不對的,還請大家指出,只是這里是一種特殊的情況中的特殊用法,這種騷操作還是不要推廣的好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容