Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server : Using recursive CTE to resolve group membership

I have one table (users_groups) :

+-----------+------------+---------+
| groupGUID | memberGUID | isGroup |
+-----------+------------+---------+
|  32AB160C |   5B277276 |       0 |
|  32AB160C |   0A023D1D |       0 |
|  5C952B2E |   32AB160C |       1 |
|  4444FTG5 |   5C952B2E |       1 |
+-----------+------------+---------+

isGroup column indicates whether memberGUID is a group or not.

I want to obtain a new table (new_users_groups) with all group memberships resolved :

+-----------+------------+
| groupGUID | memberGUID |
+-----------+------------+
|  32AB160C |   5B277276 |
|  32AB160C |   0A023D1D |
|  5C952B2E |   5B277276 |
|  5C952B2E |   0A023D1D |
|  4444FTG5 |   5B277276 |
|  4444FTG5 |   0A023D1D |
+-----------+------------+

For now, I'm doing everything manually :

  1. Looking for all group's memberGUID

    SELECT * FROM users_groups WHERE isGroup = 1;

  2. For all groups returned by previous step, find its members

    SELECT * FROM users_groups WHERE groupGUID = '5C952B2E'

  3. If members are not groups, insert them into a new table

    INSERT INTO new_users_groups (groupGUID, memberGUID) VALUES ('5C952B2E', '5B277276'); INSERT INTO new_users_groups (groupGUID, memberGUID) VALUES ('5C952B2E', '0A023D1D');

  4. If members are groups, go to step 2.

How can I automate this? Maybe with a Recursive CTE ?

like image 780
Trevor65 Avatar asked Aug 08 '18 11:08

Trevor65


People also ask

What is a recursive CTE in SQL?

Code language:SQL (Structured Query Language)(sql) In general, a recursive CTE has three parts: An initial query that returns the base result set of the CTE. The initial query is called an anchor member. A recursive query that references the common table expression, therefore, it is called the recursive member.

What is the recursive member in SQL Server?

A recursive query that references the common table expression, therefore, it is called the recursive member. The recursive member is union-ed with the anchor member using the UNION ALL operator. A termination condition specified in the recursive member that terminates the execution of the recursive member.

What are the four elements of a recursive CTE?

A recursive CTE requires four elements in order to work properly. Anchor query (runs once and the results ‘seed’ the Recursive query) Recursive query (runs multiple times and is the criteria for the remaining results) UNION ALL statement to bind the Anchor and Recursive queries together.

How to bind anchor and recursive queries together in a CTE?

A recursive CTE requires four elements in order to work properly. UNION ALL statement to bind the Anchor and Recursive queries together. INNER JOIN statement to bind the Recursive query to the results of the CTE.


1 Answers

You can do this with a recursive CTE:

with cte as (
  select ug.groupGUID, ug.groupGUID as grp, ug.memberGUID
  from user_groups ug
  where isGroup = 0
  union all
  select ug.groupGUID, ug.groupGUID as grp, cte.memberGUID
  from user_groups ug join
       cte
       on cte.grp = ug.memberGUID
 )
select groupGUID, memberGUID
from cte;

Here is a Rextester.

like image 51
Gordon Linoff Avatar answered Nov 03 '22 23:11

Gordon Linoff