在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/人工智能  數(shù)據(jù)庫/ mysql左右值樹怎樣計算某層節(jié)點數(shù)據(jù)?

mysql左右值樹怎樣計算某層節(jié)點數(shù)據(jù)?

公司是做直銷系統(tǒng)的,因為業(yè)務(wù)需要,給客戶做一個雙軌會員制系統(tǒng)設(shè)計。里面會員關(guān)系用到了左右值數(shù)計算。

雙軌就是,每個節(jié)點只允許最多有兩個直接子節(jié)點。

左區(qū),就是某個節(jié)點下面左邊的節(jié)點列表
右區(qū),就是某個節(jié)點下面右邊的節(jié)點列表

要結(jié)算對碰獎金,我現(xiàn)在需要計算出以某層為根節(jié)點,能夠獲得第N層的左區(qū)或者右區(qū)節(jié)點數(shù)據(jù)。
我的表結(jié)構(gòu)數(shù)據(jù)是這樣的,

圖片描述

表名:kt_relation
relation_id :沒啥用,一般沒用他
user_id :這是會員id,我用他來記錄某個節(jié)點左右區(qū)是否已經(jīng)占用。
Lft:左值
Rgt:右值
Lft_sub:某會員id左區(qū)是哪個會員,沒有就是0,
Rgt_sub:某會員id右區(qū)是哪個會員,沒有就是0.
Level:層數(shù),跟節(jié)點是第一層。也就是所在樹中的深度。

我算出來了,以跟節(jié)點為準10001,第N層的左右區(qū)節(jié)點列表,sql語句是這樣的。

Child.user_id, Child.Lft, Child.Rgt,Child.Level
            FROM kt_relation as Child, kt_relation as Parent
                WHERE
                  Child.Level = 3
                  AND Child.Lft+Child.Rgt <= Parent.Lft +Parent.Rgt
                  AND Parent.user_id = 10001

核心就是:Lft+Rgt<=Lft+Rgt,某個父親子節(jié)點左右值之和<=父親節(jié)點的左右值之和,那么他就是父親節(jié)點的左區(qū),然后我想查看第3層,看看有哪些節(jié)點。

組織架構(gòu)圖

現(xiàn)在我想查詢,如上圖黃色的user_id是10003的,這個節(jié)點,他的左區(qū)的第三層是哪些節(jié)點,應(yīng)該是綠色那兩個節(jié)點。現(xiàn)在就是卡到這里,弄不動了。

我自己的想法是,還是用上面那種sql從根節(jié)點開始,10003的第三層應(yīng)該是10001的第4層,10003在10001的右區(qū),那么我就把10001的左區(qū)都排除,只查詢10001第4層的右區(qū)有多少節(jié)點,顯然把10013也包含進去了。這個又堵住了,感覺行不通。即便可行,也存在一個問題。就是要好多條sql語句,才能完成最終結(jié)果。有沒有辦法,只用像上面那種一條就出結(jié)果的,查詢耗時在0.035s,0.02s這種的語句。

因為不想在這里太耗時,后面還有很多計算獎金的查詢,更新什么的,又要耗時間。盡可能查詢時間短點。我都做了索引了。

不知道我說清楚沒有,有大俠對左右值算法有研究的朋友,指點指點。

回答
編輯回答
不將就
SELECT Child.user_id, Child.Lft, Child.Rgt,Child.Level
            FROM kt_relation as Child, kt_relation as Parent
                WHERE
                  Child.Level = 3+1
                  -- AND Child.Lft+Child.Rgt <= Parent.Lft +Parent.Rgt   -- 左區(qū)
                                    
                                    AND Child.Lft+Child.Rgt > Parent.Lft +Parent.Rgt    -- 右區(qū)
                  
                                    AND Parent.user_id = 10001
                                    
                                    AND Child.Lft+Child.Rgt <= 12 +25

搞出來了一個sql語句,可以實現(xiàn)。前提是確認這個節(jié)點是最頂層節(jié)點10001的哪個區(qū)域,然后查10001的右區(qū),再加個條件,查詢10003的左區(qū),12+25就能代表10003了。
這種自連接,搞的我有點暈乎!速度還可以,可能是有索引的原因。
php里面就是,先取得待查的節(jié)點10003的記錄,取出他的,左右值。
然后計算出,應(yīng)該查以根節(jié)點開始的哪層。比如這個10003,要查他開始的第3層,那實際查的應(yīng)該是,10001的第4層。因為10003與10001差1層。所以是,3+1層。什么亂七八糟的。

搞出來個簡單的,先查出這個節(jié)點的所有子孫節(jié)點,加條件,和值小于自身,再限定定層。就出來了。
SELECT * FROM Tree WHERE Lft > 1 AND Lft < 26 AND Lft + Rgt <= 1 + 26 AND Level = 4

為什么,我把問題寫出來,然后不久,自己就解決了問題,好怪。不寫就整不出來。其實我就是個菜b

2017年6月26日 06:56