开发者

SQL Server Distinct Union for one column

开发者 https://www.devze.com 2023-04-03 13:46 出处:网络
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/overrid

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
0

精彩评论

暂无评论...
验证码 换一张
取 消