SQL Server Distinct Union для одного столбца - PullRequest
3 голосов
/ 07 сентября 2011

Я с трудом разбираюсь с запросом SQL, который мне нужен для ситуации.

У меня есть проект, который имеет пользовательские роли уровня студии для пользователя, и у каждого проекта есть роли уровня проекта, которые перекрывают / перекрывают роли уровня студии. Все роли определены на уровне студии, но только некоторые роли определены на уровне проекта (в основном роли, которые имеют значения, отличные от их соответствующей роли уровня студии)

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

Мне нужен запрос, который перекрывает роли проекта над ролями студии для данного идентификатора проекта. Самое сложное - избежать дублирования роли на уровне студии. Мне нужны роли уровня проекта (если есть), чтобы доминировать.

Я играл с Союзами, но не могу понять, как избежать дубликатов.

В основном мне нужны следующие результаты:

userId  roleId  value
1       1       TRUE
1       2       FALSE
1       3       TRUE
2       1       TRUE

Где

  • userId of 1, roleId of 2 имеет значение False
  • userId из 2, roleId из 1 имеет значение True

как указано на уровне проекта

Я думал, что был близок к этому запросу, но дубликаты все еще присутствуют:

;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 (SELECT DISTINCT RoleId FROM roles) AS distinctRoles
ON distinctRoles.RoleId = roles.RoleId

1 Ответ

7 голосов
/ 07 сентября 2011

Вам не нужен союз.Просто левое присоединение к проекту из студии и затем используйте coalesce

следующее

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

Возвращает следующий результат

userId      roleId      value
----------- ----------- -----
1           1           TRUE
1           2           FALSE
1           3           TRUE
2           1           TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...