Reputation: 863
I am using SQL Server 2008. I have a table which details useraccess to groups with two columns - userid int
and groupid int
(let's call it tbl_access
). Each user can have access to multiple groups at any level in the tree.
There is a second table of groups defining a tree structure with three columns - groupid int
, groupfather int
, groupname nvarchar(32) (top level groups have a value of -1 for groupfather
) - let's call it tbl_groups
.
I am trying to write a function where given a userid
, the function will look up all the groups the user can access in tbl_access
, and for each group it will then find all of child nodes, and return a combined distinct list of all the groups the user has access to).
I have tried using CTE but that only got me so far as getting all the child nodes of one group, not all the child nodes of all groups.
What i have for now is :
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
Upvotes: 1
Views: 153
Reputation: 8832
You can use a recursive CTE, for your function you can use the following query:
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
Upvotes: 2