2014-10-31 81 views
1

我有下面的表結構更好的方法來寫這個SQL查詢

用戶(PK - 用戶ID)
系統(PK - SYSTEMID)
SystemRoles(PK-SystemRoleId,FK - SYSTEMID)
的UserRole(PK-用戶ID & SystemRoleId,FK-SystemRoleId,FK-用戶Id)

Users可以訪問不同Systems和一個System可以定義不同的SystemRoles

現在,我需要刪除Users誰有SystemRoles分配給他們只爲一個特定的System(s)。如果他們爲其他Systems定義了SystemRoles,則不應刪除它們。

我已經拿出下面的查詢來標識符合刪除條件的記錄,但認爲這肯定會被優化。有什麼建議麼?

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

它有什麼問題?它慢嗎?你確定它很慢嗎?如果它沒有損壞... – DLeh 2014-10-31 16:18:34

+0

如果沒有任何問題,也許http://codereview.stackexchange.com是一個更好的去處。 – DLeh 2014-10-31 16:19:13

+0

你還沒有忘記添加索引,對不對?特別是對於唯一的ID – 2014-10-31 16:20:46

回答

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

正好符合我將與...運行...很好,乾淨。一次通過,檢查兩者。我會稍微改變最大值(條件/ 1/0的情況下)和最大值(NOT條件/ 1/0的情況下),這就是其他。 – DRapp 2014-10-31 17:14:14

+0

爲方法。與進行2次通過檢查相比,在性能方面沒有區別。兩者都在一秒內返回約200,000條記錄。執行計劃在系統表上顯示索引掃描,而對於另一個查詢則爲索引搜索。這對我來說肯定不是問題,因爲System表中只有不到50行,我不知道如果System表有幾千行,這個查詢將如何執行。 – 2014-11-03 11:45:36

相關問題