2012-09-15 5 views
1

SQL Server 2008을 사용하고 있습니다. 두 개의 열 (userid intgroupid int)의 그룹에 대해 사용자 액세스를 상세하게 설명하는 테이블이 있습니다 (tbl_access라고 부름). 각 사용자는 트리의 모든 레벨에서 여러 그룹에 액세스 할 수 있습니다.SQL 트리에서 다중 재귀

세 개의 열이있는 트리 구조를 정의하는 그룹의 두 번째 테이블이있다 - groupid intgroupfather int이 그룹 이름의 NVARCHAR (32) (최상위 그룹이 groupfather -1의 값이) -의이 tbl_groups을 부르 자가.

주어진 함수가 userid 인 경우 함수는 사용자가 tbl_access에 액세스 할 수있는 모든 그룹을 조회하고 모든 그룹에 대해 모든 하위 노드를 찾아 결합 된 고유 목록을 반환합니다. 사용자가 액세스 할 수있는 모든 그룹).

나는 CTE를 사용해 보았지만, 모든 그룹의 모든 자식 노드가 아니라 하나의 그룹의 모든 자식 노드를 얻는 것만이 가능했다.

무엇 내가 지금있는 것은 :

CREATEFUNCTION [DBO].[FUNC_ALL_CHILDGROUPS] (@GROUPID INT) 
RETURNS TABLE 
AS 
RETURN (
    WITH ALLGROUPS (GROUPID, GROUPFATHER) AS 
    (
     SELECT GROUPID, GROUPFATHER 
     FROM 
      TBL_GROUPS 
     WHERE GROUPID = @GROUPID 

     UNION ALL 

     SELECT TBL_GROUPS.GROUPID, TBL_GROUPS.GROUPFATHER 
     FROM 
      TBL_GROUPS 
      INNER JOIN ALLGROUPS 
      ON TBL_GROUPS.GROUPFATHER = ALLGROUPS.GROUPID 
    ) 
SELECT * FROM ALLGROUPS 

답변

2

당신은 재귀 CTE를 사용할 수 있습니다, 당신의 기능에 다음과 같은 쿼리를 사용할 수 있습니다

DECLARE @tbl_access TABLE (userid INT, groupid INT) 
DECLARE @tbl_groups TABLE (groupid INT, groupfather INT) 

INSERT @tbl_access 
VALUES 
(1, 2), 
(1, 3), 
(2, 1), 
(2, 4) 

INSERT @tbl_groups 
VALUES 
(1, -1), 
(2, 1), 
(3, -1), 
(4, 2), 
(5, 4) 

DECLARE @UserID INT = 1 

;WITH cte AS (

    SELECT a.* 
    FROM @tbl_groups a 
    JOIN @tbl_access c ON 
      c.userid = @UserID 
    AND  c.groupid = a.groupid 

    UNION ALL 

    SELECT b.* 
    FROM @tbl_groups b 
    JOIN cte d ON 
      d.groupid = b.groupfather 
) 

SELECT DISTINCT groupid 
FROM cte 
+0

작동 완벽하게. 고맙습니다. – user1480192

+0

@ user1480192 좋아요. 기꺼이 도와 드리겠습니다. :) –