当前位置:  开发笔记 > 编程语言 > 正文

SQL递归

如何解决《SQL递归》经验,为你挑选了1个好方法。

我有下一张桌子.groups表包含按层次排序的组和group_member,用于存储用户所属的组.

groups
---------
id  
parent_id
name

group_member
---------
id
group_id
user_id

ID  PARENT_ID  NAME
---------------------------
1   NULL       Cerebra
2   1          CATS 
3   2          CATS 2.0 
4   1          Cerepedia 
5   4          Cerepedia 2.0
6   1          CMS 

ID GROUP_ID USER_ID
---------------------------
1  1        3
2  1        4
3  1        5
4  2        7
5  2        6
6  4        6
7  5        12
8  4        9
9  1        10

我想检索给定用户的可见组.这就是说用户属于的组和这些组的子组.例如,使用以上数据:

USER  VISIBLE_GROUPS
9     4, 5 
3     1,2,4,5,6
12    5 

我使用递归和几个数据库查询获取这些值.但我想知道是否可以使用单个SQL查询来提高我的应用程序性能.我正在使用MySQL.



1> JosephStyons..:

我想到两件事:

1 -您可以反复将表外连接到自身,以递归方式向上走树,如下所示:

SELECT *
FROM
  MY_GROUPS MG1
 ,MY_GROUPS MG2
 ,MY_GROUPS MG3
 ,MY_GROUPS MG4
 ,MY_GROUPS MG5
 ,MY_GROUP_MEMBERS MGM
WHERE MG1.PARENT_ID = MG2.UNIQID (+)
  AND MG1.UNIQID = MGM.GROUP_ID (+)
  AND MG2.PARENT_ID = MG3.UNIQID (+)
  AND MG3.PARENT_ID = MG4.UNIQID (+)
  AND MG4.PARENT_ID = MG5.UNIQID (+)
  AND MGM.USER_ID = 9

那会给你这样的结果:

UNIQID PARENT_ID NAME      UNIQID_1 PARENT_ID_1 NAME_1 UNIQID_2 PARENT_ID_2 NAME_2  UNIQID_3 PARENT_ID_3 NAME_3 UNIQID_4 PARENT_ID_4 NAME_4 UNIQID_5 GROUP_ID USER_ID
4      2         Cerepedia 2        1           CATS   1        null        Cerebra null     null        null   null      null       null   8        4        9

这里的限制是您必须为要在树上行走的每个"级别"添加新的连接.如果你的树的数量少于20级,那么你可以通过创建一个显示每个用户20个级别的视图来逃避它.

2 -我所知道的唯一其他方法是创建递归数据库函数,并从代码中调用它.你仍然会有一些查询开销(也就是说,你的#查询仍然等于你在树上行走的等级数),但总体来说它应该更快,因为它全部发生在数据库中.

我不确定MySql,但在Oracle中,这样的函数与此类似(你必须更改表和字段名称;我只是复制我过去做过的事情):

CREATE OR REPLACE FUNCTION GoUpLevel(WO_ID INTEGER, UPLEVEL INTEGER) RETURN INTEGER
IS
BEGIN
  DECLARE
    iResult INTEGER;
    iParent INTEGER;
BEGIN
  IF UPLEVEL <= 0 THEN
    iResult := WO_ID;
  ELSE
    SELECT PARENT_ID
    INTO iParent
    FROM WOTREE
    WHERE ID = WO_ID;    
    iResult := GoUpLevel(iParent,UPLEVEL-1);  --recursive
  END;
  RETURN iResult;
  EXCEPTION WHEN NO_DATA_FOUND THEN
    RETURN NULL;
  END;
END GoUpLevel;
/

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有