2012-07-31 95 views
0

我有一個用戶ID值列表A列有管理用戶,列B有用戶。例如,我希望能夠顯示管理其他用戶的用戶列表。在MySQL中生成分層數據集

 
User 1 can manage user 2 
User 1 can manage user 3 
User 3 can manage user 4 
User 5 can manage user 6 

這將產生如下表:

 
-------------------------- 
| mgtuserId | userId | 
-------------------------- 
|  1  |  2 | 
|  1  |  3 | 
|  3  |  4 | 
|  5  |  6 | 
-------------------------- 

我想有一個查詢或存儲過程,按照下來的層次結構返回管理用戶的列表。因此,如果您是用戶1,則會輸出以下列表。

 1, 2, 3, 4

然後,如果你是用戶2,那麼你將只有2輸出。

 2

然後,如果您是用戶5,則輸出以下列表,依此類推。

 5, 6

什麼是最好的方式來實現這個給定的,我有每個用戶ID。

在此先感謝。

回答

1

替換您的表名

DELIMITER $$ 

CREATE PROCEDURE get_users(IN base INT UNSIGNED) 
BEGIN 
DECLARE ids TEXT DEFAULT ''; 

SET @parents = base; 
SET ids = base; 

loop1: LOOP 
    SET @stm = CONCAT(
     'SELECT GROUP_CONCAT(userId) INTO @parents FROM YOUR_TABLE', 
     ' WHERE mgtuserId IN (', @parents, ')' 
    ); 

    PREPARE fetch_childs FROM @stm; 
    EXECUTE fetch_childs; 
    DROP PREPARE fetch_childs; 

    IF @parents IS NULL THEN LEAVE loop1; END IF; 

    SET ids = CONCAT(ids, ',', @parents); 
END LOOP; 

SET @stm = CONCAT('(SELECT mgtuserId FROM YOUR_TABLE WHERE mgtuserId=',base,') UNION (SELECT userId FROM YOUR_TABLE WHERE userId IN (',ids, '))'); 

PREPARE fetch_childs FROM @stm; 
EXECUTE fetch_childs; 
DROP PREPARE fetch_childs; 
END; 

檢查

CALL get_users(1); 
1 
2 
3 
4 

YOUR_TABLE和my.ini的

設置
thread_stack = 256K 
0

給你一些搜索條件:你正在尋找你的關係的傳遞閉包,它需要遞歸查詢。據我所知,recusrive查詢不能在MySQL中表示,除非藉助存儲過程或函數。

a search中使用上述一些術語會給你提供大量與你密切相關的問題和答案。 how to work with recursive query in MySql?就是其中之一。那裏的答案鏈接到a document,它描述了一個PROCEDURE recursivesubtree,這可能是您實施的一個很好的起點。

0

您輸出的規範會導致我所做的操作稍有不同。

假設您沒有任何「循環」,並且沒有mgtuserId = userId的任何行,您可以通過多次將表連接到自己來仿真深層次查詢N級,如下所示:

SELECT n0.userId AS n0_userId 
    , n1.userId AS n1_userId 
    , n2.userId AS n2_userId 
    , n3.userId AS n3_userId 
    , n4.userId AS n4_userId 
    , n5.userId AS n5_userId 
    , n6.userId AS n6_userId 
    FROM mytable n0 
    LEFT JOIN mytable n1 ON n1.mgtuserId = n0.userId 
    LEFT JOIN mytable n2 ON n2.mgtuserId = n1.userId 
    LEFT JOIN mytable n3 ON n3.mgtuserId = n2.userId 
    LEFT JOIN mytable n4 ON n4.mgtuserId = n3.userId 
    LEFT JOIN mytable n5 ON n5.mgtuserId = n4.userId 
    LEFT JOIN mytable n6 ON n6.mgtuserId = n5.userId 
WHERE n0.userId = 1 

但是,此查詢不會返回您指定的結果集,逗號分隔的列表。

此查詢返回的每一行表示從樹中指定的起點到每個葉節點(或者在此情況下,每個節點不超過六個級別深度(在指定起始點之下)的「路徑」點)。

不,現在不是很漂亮,但你可以看到這是如何可以擴展到N級。

,我沒有看到這個轉換到結果集指定一個好辦法

我可能不得不做同樣的事情,但要獲得每個級別的單獨查詢(一級深度,兩級深度等)和t母雞使用UNION ALL來組合它們。但那會更醜陋。爲了得到一個未指定數量的層次到每個葉節點,我們真的需要使用一個臨時表,並且迭代地執行相同類型的查詢。但當然,這不是一個單一的查詢。

(我將在返回您指定的結果集的解決方案工作。)