2012-07-31 91 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来组合它们。但那会更丑陋。为了得到一个未指定数量的层次到每个叶节点,我们真的需要使用一个临时表,并且迭代地执行相同类型的查询。但当然,这不是一个单一的查询。

(我将在返回您指定的结果集的解决方案工作。)