I'm having a rough time figuring out the SQL query I need for a situation.
I have a project that has studio level user roles for a user, and each project has project level roles that overlay/override the studio level roles. All roles are defined at the studio level, but only some roles are defined at the project level (mainly roles that have different values than their corresponding studio level role)
g_studio_UsersInRole
userId roleId value
1 1 TRUE
1 2 TRUE
1 3 TRUE
2 1 FALSE
g_project_UsersInRole
userId roleId value projectId
1 2 FALSE 1
2 1 TRUE 1
I need a query that overlays the project roles over the studio roles for a given project Id. The tricky part is avoiding the duplicate studio level role. I need the project level roles (if any) to dominate.
I've been playing with Unions, but I can't figure out how to avoid the duplicates.
Basically I need the following results:
userId roleId value
1 1 TRUE
1 2 FALSE
1 3 TRUE
2 1 TRUE
Where
- userId of 1, roleId of 2 has a value False
- userId of 2, roleId of 1 has a value True
as indicated in the project level
I thought I was close with this query, but the duplicates are still present:
;With roles As
(
SELECT UserId, Value, RoleId
FROM dbo.g_project_UsersInRole
WHERE (ProjectId = 1)
UNION
SELECT UserId, Value, RoleId
FROM dbo.g_studio_UsersInRole)
SELECT roles.RoleId, Value, UserId
FROM roles
RIGHT JOIN (SE开发者_开发技巧LECT DISTINCT RoleId FROM roles) AS distinctRoles
ON distinctRoles.RoleId = roles.RoleId
You don't need a union. Just a left join to project from studio and then use coalesce
the following
WITH g_studio_UsersInRole AS --Sampledata
(
SELECT 1 userId ,1 roleId , 'TRUE' value
UNION SELECT 1, 2, 'TRUE'
UNION SELECT 1, 3, 'TRUE'
UNION SELECT 2, 1, 'FALSE')
, g_project_UsersInRole as --Sampledata
(
SELECT 1 userId , 2 roleId , 'FALSE' value , 1 projectId
UNION SELECT 2, 1, 'TRUE', 1
)
SELECT
sRole.userId,
sRole.roleId,
COALESCE(pRole.Value,sRole.value) as value
FROM
g_studio_UsersInRole sRole
LEFT JOIN g_project_UsersInRole pRole
ON sRole.userId = pRole.userId
and sRole.roleId = pRole.roleId
and pRole.ProjectId = 1
Returns the following result
userId roleId value
----------- ----------- -----
1 1 TRUE
1 2 FALSE
1 3 TRUE
2 1 TRUE
精彩评论