2009-10-21 103 views
8

我中有你軋機組嵌套層次類型設置的運行有以下欄目:MySQL嵌套集 - 如何找到節點的父節點?

表名:

myset 

列:

id, name, lft, rgt 

有誰知道一個查詢,以確定父節點的一個節點?

我讀了幾個地方,它很方便也有你的表PARENT_ID列以跟蹤這一點,但它似乎是多餘的,它似乎是它可以得到不同步嵌套組如果查詢在添加/刪除/移動集合中的任何內容時被錯誤執行。

回答

17

看看this question。它與你的相似。我在那裏發佈了您可能需要的查詢。

SELECT title, (SELECT TOP 1 title 
      FROM tree t2 
      WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt  
      ORDER BY t2.rgt-t1.rgt ASC) AS parent 
FROM tree t1 
ORDER BY rgt-lft DESC 

我希望有你需要的東西。

爲下表:

+-------------+----------------------+-----+-----+ 
| category_id | name     | lft | rgt | 
+-------------+----------------------+-----+-----+ 
|   1 | ELECTRONICS   | 1 | 20 | 
|   2 | TELEVISIONS   | 2 | 9 | 
|   3 | TUBE     | 3 | 4 | 
|   4 | LCD     | 5 | 6 | 
|   5 | PLASMA    | 7 | 8 | 
|   6 | PORTABLE ELECTRONICS | 10 | 19 | 
|   7 | MP3 PLAYERS   | 11 | 14 | 
|   8 | FLASH    | 12 | 13 | 
|   9 | CD PLAYERS   | 15 | 16 | 
|   10 | 2 WAY RADIOS   | 17 | 18 | 

它產生的輸出:

title    | parent 
---------------------------------------------- 
ELECTRONICS   | NULL 
PORTABLE ELECTRONICS | ELECTRONICS 
TELEVISIONS   | ELECTRONICS 
MP3 PLAYERS   | PORTABLE ELECTRONICS 
FLASH    | MP3 PLAYERS 
CD PLAYERS   | PORTABLE ELECTRONICS 
2 WAY RADIOS   | PORTABLE ELECTRONICS 
TUBE     | TELEVISIONS 
LCD     | TELEVISIONS 
PLASMA    | TELEVISIONS 
+0

你知道爲什麼'ORDER BY t2.rgt-t1.rgt'會在sqlite中返回錯誤嗎? 'SQLSTATE [HY000]:一般錯誤:1沒有這樣的列:t1.rgt' ...它工作時,我從訂單中刪除t1.rgt所以它似乎是一個問題與秩序... – Stoner 2017-10-24 14:23:25

0

所有祖先都被

SELECT id FROM thetable 
WHERE x BETWEEN lft and rgt; 

所以回來了,直接父與祖先lft和rgt之間的最小差異。

SELECT id FROM thetable 
WHERE x BETWEEN lft and rgt 
ORDER BY (rgt-lft) 
LIMIT 1 
+1

如果你的x應該成爲元素的id,而不是你的陳述是錯誤的。 – spankmaster79 2010-08-17 11:50:26

2

我對盧卡斯的查詢有問題。我的mysql版本不理解TOP命令。我不得不使用LIMIT。這是修改後的代碼。

SELECT 
    `id`, 
    (SELECT 
     `id` 
    FROM 
     `[*** YOUR TABLE ***]` AS `t2` 
    WHERE 
     `t2`.`left_id` < `t1`.`left_id`AND 
     `t2`.`right_id` > `t1`.`right_id` 
    ORDER BY 
     `t2`.`right_id`-`t1`.`right_id`ASC 
    LIMIT 
     1) AS `parent` 
FROM 
    `[*** YOUR TABLE ***]` AS `t1` 
WHERE 
    `t1`.`id` = [*** ID OF THE NODE WHOS PARENT YOU WISH TO LOOKUP ***] 
ORDER BY 
    `right_id`-`left_id` DESC 

顯然,更改[]中的內容以滿足您的需求。同時刪除[]。該查詢只返回一行。是這樣的...

id parent 
7 3 
14

TOP是MSSQL命令,使用極限爲MySQL:

SELECT title, (SELECT title 
     FROM tree t2 
     WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt  
     ORDER BY t2.rgt-t1.rgt ASC 
     LIMIT 1) 
AS parent FROM tree t1 
ORDER BY (rgt-lft) DESC 

應該做的伎倆..

0

從spankmaster79的代碼是不是完全錯誤的。我修改了他的代碼,它工作。

SELECT parent . * FROM Nested_Category AS node, Nested_Category AS parent 
enter code hereWHERE node.leftSide 
BETWEEN parent.leftSide 
AND parent.rightSide 
AND node.id ='Enter the Node ID' 
ORDER BY (
parent.rightSide - parent.leftSide 
) 
LIMIT 1 , 1 
0
select * from myset 
    where lft < :lftOfCurrent and rgt > :lftOfCurrent 
    order lft desc 
    limit 1 

你可以使用一個最大而不是順序/限制,您可能需要另一個關鍵字根據您的數據庫中的結果限制爲一行。如果你的數據庫返回的是獨佔集,而不是<和>之間,MySQL不會。

3

只是添加到這些答案這幫助了我很多,

我需要找到一個節點的直接父,以及在某些情況下,一個節點鏈的最高層父,

我用下面爲基地,讓兒童對父母爲了

SELECT parent.* FROM 
     nested_set node, 
     nested_set parent 
     WHERE (
      node.set_left BETWEEN parent.set_left AND parent.set_right   
     ) 
     AND node.set_id={CHILD_NODE_ID_HERE} 
     ORDER BY parent.set_right - parent.set_left 
     #LIMIT 1,1 

的項目是然後加入LIMIT 1,1只捕捉第二排的事項,將是直接父

還應當指出的是,如果節點本身就是最高層父上面的查詢,那麼它不會有一個直接父,所以與LIMIT 1,1它應該返回一個空的結果集

得到最高層父我一條一條地順序顛倒,包括一個檢查,如果節點本身是頂級的父母,並在最後一個查詢的限制,結果第一行

SELECT parent.* AS top_level_right FROM 
     nested_set node, 
     nested_set parent 
     WHERE (
      node.set_left >= parent.set_left 
      AND node.set_left <= parent.set_right 
     ) 
     AND node.set_id={CHILD_NODE_ID_HERE} 
     ORDER BY parent.set_left - parent.set_right 
     LIMIT 1 

我用>= <=運營者所選範圍包含子節點,如果它也發生的話成爲頂級父項

1
SELECT parent.name 
FROM myset AS node, myset AS parent 
WHERE parent.lft < node.lft 
AND parent.rgt > node.rgt 
AND node.id = {YOUR CATEGORY ID} 
ORDER BY (parent.rgt - parent.lft) ASC LIMIT 1;