Question

I have the following situation and I am not sure how best to address it. Any guidance on how to prepare the needed view would be greatly appreciated.

I have 4 tables:
users (userid int, username varchar)
roles (roleid int, rolename varchar)
businessunit (buid int, buname varchar)
user_role_map (userid, roleid, buid)

In the roles table I have a role with the id of 0 which is the "system admin" role and in the businessunit table I have an IT business unit. Any users resulting from the below query would be considered system admins and should have full access to every business unit.

SELECT userid FROM user_role_map WHERE roleid = 0 AND buid = 0

I need to build a view that shows all "non system admins" union'd to a list of every business unit and every "system admin" user. The first part is easy with the below query, but the second part is what what I am struggling with.

SELECT userid, roleid, buid FROM user_role_map WHERE roleid > 0 AND buid > 0

I will give some example data to help illustrate what I am trying to accomplish:

users
---------------
1, "sysAdmin"  
2, "salesUser1"  
3, "serviceUser1"  
4, "manager1"  
5, "salesUser2"
6, "serviceUser2"
7, "manager2"
roles
---------------
0, "SystemAdmin"
1, "Full"
2, "Update"
3, "Read"

businessunit --------------- 0, "IT" 1, "fooSales" 2, "fooService" 3, "barSales" 4, "barService"

user_role_map
---------------
1, 0, 0
2, 1, 1
2, 3, 3
3, 1, 2
3, 3, 4
4, 1, 1
4, 1, 2
5, 1, 3
5, 3, 1
6, 1, 4
6, 3, 3
7, 1, 2
7, 1, 4

Finally, i need the view to provide the following for the above sample data (note the last 4 rows):

new view
---------------
2, 1, 1
2, 3, 3
3, 1, 2
3, 3, 4
4, 1, 1
4, 1, 2
5, 1, 3
5, 3, 1
6, 1, 4
6, 3, 3
7, 1, 2
7, 1, 4
1, 1, 1
1, 1, 2
1, 1, 3
1, 1, 4

NOTE: the example data here only has one "System Admin" user but there could be any number of users of this type.

Was it helpful?

Solution

You should be able to do something like this:

declare @users table(userid int, username varchar(255));
insert into @users values (1, 'sysAdmin');
insert into @users values (2, 'salesUser1');  
insert into @users values (3, 'serviceUser1');  
insert into @users values (4, 'manager1');  
insert into @users values (5, 'salesUser2');
insert into @users values (6, 'serviceUser2');
insert into @users values (7, 'manager2');


declare @roles table(roleid int, rolename varchar(255));
INSERT INTO @roles VALUES (0, 'SystemAdmin');
INSERT INTO @roles VALUES (1, 'Full');
INSERT INTO @roles VALUES (2, 'Update');
INSERT INTO @roles VALUES (3, 'Read');

DECLARE @user_role_map TABLE(userid INT, roleid INT, buid int)
INSERT INTO @user_role_map values (1, 0, 0);
INSERT INTO @user_role_map values (2, 1, 1);
INSERT INTO @user_role_map values (2, 3, 3);
INSERT INTO @user_role_map values (3, 1, 2);
INSERT INTO @user_role_map values (3, 3, 4);
INSERT INTO @user_role_map values (4, 1, 1);
INSERT INTO @user_role_map values (4, 1, 2);
INSERT INTO @user_role_map values (5, 1, 3);
INSERT INTO @user_role_map values (5, 3, 1);
INSERT INTO @user_role_map values (6, 1, 4);
INSERT INTO @user_role_map values (6, 3, 3);
INSERT INTO @user_role_map values (7, 1, 2);
INSERT INTO @user_role_map values (7, 1, 4);

DECLARE @businessunit TABLE(buid int, buidname VARCHAR(255));
INSERT INTO @businessunit VALUES (0, 'IT')
INSERT INTO @businessunit VALUES (1, 'fooSales')
INSERT INTO @businessunit VALUES (2, 'fooService')
INSERT INTO @businessunit VALUES (3, 'barSales')
INSERT INTO @businessunit VALUES (4, 'barService')

--non-admin users
SELECT userid, roleid, buid 
FROM @user_role_map 
WHERE 
    roleid > 0 AND buid > 0

UNION ALL

--get admin users and add a full control entry
SELECT userid, 1, BusinessUnits.buid 
FROM @user_role_map m
CROSS JOIN(
    --use this if you have a businessunit table you can leverage; otherwise, 
    --you can select distinct buid on role_map where  buid > 0
    SELECT buid
    FROM @businessunit
    WHERE buid > 0
) AS BusinessUnits
WHERE 
    roleid = 0 AND m.buid = 0

OTHER TIPS

You could append the business unit's with a UNION ALL to your view.

SELECT 
    userid, 
    roleid, 
    buid 
FROM 
    user_role_map 
WHERE 
    roleid > 0 
  AND buid > 0

UNION ALL

/* append full control for system admins to all bussiness units */

SELECT 
    CAST(1 AS INT) AS userid, 
    CAST(1 as INT) AS roleid, 
    BU.buid 
FROM businessunit BU
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top