2015-12-07 42 views
2

我有MySQL表是這樣的:MySQL的:獲取使用PARENT_ID所有層級從表

id | name| parent_id 
---+-----+----------- 
1 | aaa | 0 
2 | bbb | 1 
3 | ccc | 2 
4 | ddd | 3 
5 | eee | 3 
6 | fff | 1 
7 | ggg | 0 
8 | hhh | 7 
9 | iii | 7 

我需要創建一個查詢,將獲取所有層次爲給定ID。

例如:輸入= 1時,結果應該是這樣的:

id | name| parent_id 
---+-----+----------- 
1 | aaa | 0 
2 | bbb | 1 
3 | ccc | 2 
4 | ddd | 3 
5 | eee | 3 
6 | fff | 1 

例如:輸入= 7,結果應該是這樣的:

id | name| parent_id 
---+-----+----------- 
7 | ggg | 0 
8 | hhh | 7 
9 | iii | 7 

我已經試過這樣的事情,但不知道如何着手。我不知道層次結構中有多少層。

SELECT t1.id, t1.name, t1.parent_id, t2.name AS parent_name 
FROM parent_test t1 
LEFT JOIN parent_test t2 ON t1.parent_id=t2.id 
WHERE t1.id=1 OR t1.parent_id=1; 

任何想法?

回答

2

只有父列,查詢需要遞歸執行。這是MySQL不能做的事情。

幸運的是,這是一個常見問題,有一個常見的(雖然有點複雜)解決方案:the nested set model

嵌套集模型是用於表示嵌套集合的特定技術(也被稱爲樹或層次結構)在關係數據庫中。

使用嵌套集指定leftright列。 leftright之間的所有記錄都是後代。現在

id | name| lft | rght 
---+-----+------------- 
1 | aaa | 0 | 11 
2 | bbb | 1 | 8 
3 | ccc | 2 | 7 
4 | ddd | 3 | 4 
5 | eee | 5 | 6 
6 | fff | 9 | 10 
7 | ggg | 12 | 17 
8 | hhh | 13 | 14 
9 | iii | 15 | 16 

你可以做一個簡單的查詢來獲取所有後代備案1

SELECT t1.* FROM parent_test t1 
INNER JOIN parent_test t2 ON t1.lft >= t2.lft AND t1.rght <= t2.rght 
WHERE t2.id = 1 

請注意,當讀取查詢是簡單的,複雜性添加到編寫查詢。

插入時,您需要找到正確的left。右邊總是left + 1.接下來,由於有2個插入的數字,所以對於所有高於right列的記錄,您需要將right列的值增加2。

例如,插入2的孩子。

START TRANSACTION; 
SELECT `lft` + 1, `lft` + 2 FROM parent_test WHERE id = 2 INTO @lft, @rght 
INSERT INTO parent_test (`name`, `lft`, `rght`) VALUES ('qqq', @lft, @rght); 
UPDATE parent_test SET `rght` = `rght` + 2 WHERE `rght` > @rght; 
COMMIT; 

當你刪除你做相反的邏輯。爲了更新你做兩個。

+0

感謝您的回覆。如果我們不想使用這種lft-rght技術,可以通過較少的數據庫調用和較少的PHP處理,使用PHP-MySql組合來獲得這種結果嗎? – Awan

+1

不是。使用嵌套集模型將其減少到最小數據庫調用和最小php處理讀取。否則,您正在使用遞歸處理來讀取通常非常慢的各種子記錄。 – Kickstart

+1

@Awan,** no **。這就是遞歸查詢,一次只獲取一個圖層。 –

相關問題