前端小梅子 2021-09-20 03:45:15 阅读数:430
)
最近在做的業務場景涉及到了數據庫的遞歸查詢。我們公司用的 Oracle ,眾所周知,Oracle 自帶有遞歸查詢的功能,所以實現起來特別簡單。
但是,我記得 MySQL 是沒有遞歸查詢功能的,那 MySQL 中應該怎麼實現呢?
於是,就有了這篇文章。
文章主要知識點:
在 Oracle 中是通過 start with connect by prior 語法來實現遞歸查詢的。
按照 prior 關鍵字在子節點端還是父節點端,以及是否包含當前查詢的節點,共分為四種情况。
第一種情况: start with 子節點id = ’ 查詢節點 ’ connect by prior 子節點id = 父節點id
這裏,按照條件 id=‘1001’ 對當前節點以及它的子節點遞歸查詢。查詢結果包含自己及所有子節點。
第二種情况: start with 父節點id= ’ 查詢節點 ’ connect by prior 子節點id = 父節點 id
這裏,按照條件 pid=‘1001’ 對當前節點的所有子節點遞歸查詢。查詢結果只包含它的所有子節點,不包含自己。
其實想一想也對,因為開始條件是以父節點為根節點,且向下遞歸,自然不包含當前節點。
第三種情况: start with 子節點id= ’ 查詢節點 ’ connect by prior 父節點id = 子節點id
這裏按照條件 id=‘1001’ ,對當前節點及其父節點遞歸查詢。查詢結果包括自己及其所有父節點。
第四種情况: start with 父節點id= ’ 查詢節點 ’ connect by prior 父節點id = 子節點id
這裏按照條件 pid=‘1001’,對當前節點的第一代子節點以及它的父節點遞歸查詢。查詢結果包括自己的第一代子節點以及所有父節點。(包括自己)
其實這種情况也好理解,因為查詢開始條件是以?父節點
為根節點,且向上遞歸,自然需要把當前父節點的第一層子節點包括在內。
以上四種情况初看可能會讓人迷惑,容易記混亂,其實不然。
我們只需要記住?prior 的比特置在子節點端,就向下遞歸,在父節點端就向上遞歸。
可以看到,Oracle 實現遞歸查詢非常的方便。但是,在 MySQL 中並沒有幫我們處理,因此需要我們自己手動實現遞歸查詢。
為了方便,我們創建一個部門錶,並插入幾條可以形成遞歸關系的數據。
沒錯,剛才 Oracle 遞歸,就是用的這張錶。
另外,在這之前,我們需要複習一下幾個 MYSQL中的函數,後續會用到。
函數語法:find_in_set(str,strlist)
str 代錶要查詢的字符串 , strlist 是一個以逗號分隔的字符串,如 (‘a,b,c’)。
此函數用於查找 str 字符串在字符串 strlist 中的比特置,返回結果為 1 ~ n 。若沒有找到,則返回0。
舉個栗子:
結果返回 2 。因為 b 所在比特置為第二個子串比特置。
此外,在對錶數據進行查詢時,它還有一種用法,如下:
結果返回所有 id 在 strlist 中的記錄,即 id = ‘1000’ ,id = ‘1001’ ,id = ‘1002’ 三條記錄。
看到這,對於我們要解决的遞歸查詢,不知道你有什麼啟發沒。
以向下遞歸查詢所有子節點為例。我想,是不是可以找到一個包含當前節點和所有子節點的以逗號拼接的字符串 strlist,傳進 find_in_set 函數。就可以查詢出所有需要的遞歸數據了。
那麼,現在問題就轉化為怎樣構造這樣的一個字符串 strlist 。
這就需要用到以下字符串拼接函數了。
一、字符串拼接函數中,最基本的就是 concat 了。它用於連接N個字符串,如,
關於分布式,限流+緩存+緩存,這三大技術(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。這些相關的面試也好,還有手寫以及學習的筆記PDF,都是啃透分布式技術必不可少的寶藏。以上的每一個專題每一個小分類都有相關的介紹,並且小編也已經將其整理成PDF啦
版权声明:本文为[前端小梅子]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210920034514924a.html