编写此SQL查询的更好方法

时间:2014-10-31 16:15:48

标签: sql sql-server sql-server-2008 tsql

我有以下表结构

  

用户(PK - UserId)
  系统(PK - SystemId)
  SystemRoles(PK-SystemRoleId,FK-SystemId)
  UserRoles(PK-UserId& SystemRoleId,FK-SystemRoleId,FK-UserId)

Users可以访问不同的Systems,而System可以定义不同的SystemRoles

现在,我需要删除仅为Users分配了SystemRoles SystemSystemRoles的人Systems。如果他们为其他SELECT U.* FROM ( SELECT distinct UR.UserID FROM dbo.UserRole UR INNER JOIN dbo.SystemRole SR ON (SR.SystemRoleID = UR.SystemRoleID) INNER JOIN dbo.[System] S ON (S.SystemID = SR.SystemID) WHERE S.SystemName = 'ABC' OR S.SystemName = 'XYZ' ) T INNER JOIN dbo.[User] U ON (U.UserID = T.UserID) WHERE T.UserID NOT IN ( select distinct UR.UserID from dbo.[UserRole] UR INNER JOIN dbo.SystemRole SR ON (SR.SystemRoleID = UR.SystemRoleID) INNER JOIN dbo.[System] S ON (S.SystemID = SR.SystemID) WHERE S.SystemName <> 'ABC' AND S.SystemName <> 'XYZ' ) 定义了{{1}},则不应将其删除。

我已经提出了以下查询来识别有资格删除的记录,但认为这肯定可以优化。有什么建议吗?

{{1}}

2 个答案:

答案 0 :(得分:3)

这样的事情?

select userid from (
        SELECT
            UR.UserID,
            max(case when (S.SystemName = 'ABC' OR S.SystemName = 'XYZ')
                then 1 else 0 end) as kill,
            max(case when (S.SystemName <> 'ABC' AND S.SystemName <> 'XYZ') 
                then 1 else 0 end) as keep
        FROM
            dbo.UserRole UR
            INNER JOIN dbo.SystemRole SR ON (SR.SystemRoleID = UR.SystemRoleID)
            INNER JOIN dbo.[System] S ON (S.SystemID = SR.SystemID)
        group by UR.UserID
) u where kill = 1 and keep = 0

答案 1 :(得分:1)

这种结构将为您提供所需的记录。

select yourfields  -- or delete
from userroles 
where userid in 
(select userid 
from userroles join etc
where system.name = the one you want
except
select userid 
from userroles join etc
where system.name <> the one you want
)