2011-09-07 43 views
2

我有一个艰难的时间搞清楚我需要的情况下的SQL查询。对于一列SQL Server Distinct Union

我有一个项目具有用户的工作室级别的用户角色,每个项目都具有覆盖/覆盖工作室级别角色的项目级别角色。所有的角色都在工作室级别定义,但只有一些角色是在项目级别定义(即具有不同的价值比其相应的工作室级别的角色主要角色)

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 

我需要一个查询,将项目角色覆盖在给定项目ID的工作室角色上。棘手的部分是避免重复演播室级角色。我需要项目级角色(如果有的话)来支配。

我一直在玩联盟,但我无法弄清楚如何避免重复。

基本上我需要的结果如下:

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

用户id的1
  • ,2个角色ID有假
  • 用户id的2
  • 值,1角色ID具有值为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 

回答

7

你不需要工会。只是左连接从工作室到项目,然后用凝聚

以下

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 
+0

脱帽向你达林,完美的解决方案!就在你认为你的包里装有SQL的时候,一个新的窍门就是抛出你的方式。谢谢! – Levitikon