T-Sql-用户/组权限的业务规则

时间:2018-08-06 08:24:02

标签: tsql query-optimization

我有几个名为GroupRights和UserRights的类似表。

DECLARE @UserRights TABLE (Id INT, RightId INT)

DECLARE @GroupRights TABLE (Id INT, RightId INT)

我有一个要在此处执行的业务规则:当GroupRights有记录时,应选择该记录,但如果UserRights也具有相同ID的记录,则仅选择UserRight的记录。

我在这里做了一些代码实现了

SELECT * FROM @UserRights U
UNION 
SELECT G.* FROM @GroupRights G
LEFT OUTER JOIN @UserRights U ON G.Id = U.Id
WHERE U.Id IS NULL

借助以下插入

INSERT INTO @UserRights VALUES(1, 3)
INSERT INTO @UserRights VALUES(2, 3)
INSERT INTO @UserRights VALUES(3, 3)
INSERT INTO @UserRights VALUES(5, 3)

INSERT INTO @GroupRights VALUES(1, 1)
INSERT INTO @GroupRights VALUES(2, 1)
INSERT INTO @GroupRights VALUES(3, 5)
INSERT INTO @GroupRights VALUES(4, 1)

但这涉及从用户中两次选择(我已经用实际代码创建了CTE,这是它的简化版本)。我该如何改善呢?

2 个答案:

答案 0 :(得分:0)

美好的一天,

请检查此解决方案是否满足您的需求:

;With MyCTE as (
    SELECT id,RightId, '0' c
    FROM UserRights U
    UNION 
    SELECT id,RightId, '1' c
    FROM GroupRights G
),
MyCTE2 as (
    SELECT id,RightId,c,ROW_NUMBER() OVER (partition by id order by c) RN
    from MyCTE
)
select id,RightId
from MyCTE2
where RN = 1

对于上述解决方案,我使用了以下DDL + DML:

CREATE TABLE UserRights (Id INT, RightId INT)
CREATE TABLE GroupRights (Id INT, RightId INT)

INSERT INTO UserRights VALUES(1, 3)
INSERT INTO UserRights VALUES(2, 3)
INSERT INTO UserRights VALUES(3, 3)
INSERT INTO UserRights VALUES(5, 3)
INSERT INTO GroupRights VALUES(1, 1)
INSERT INTO GroupRights VALUES(2, 1)
INSERT INTO GroupRights VALUES(3, 5)
INSERT INTO GroupRights VALUES(4, 1)

select * from GroupRights
select * from UserRights
GO

答案 1 :(得分:0)

Please check if this helps

DECLARE @UserRights TABLE (Id INT, RightId INT)
DECLARE @GroupRights TABLE (Id INT, RightId INT)

INSERT INTO @UserRights VALUES(1, 3)
INSERT INTO @UserRights VALUES(2, 3)
INSERT INTO @UserRights VALUES(3, 3)
INSERT INTO @UserRights VALUES(5, 3)

INSERT INTO @GroupRights VALUES(1, 1)
INSERT INTO @GroupRights VALUES(2, 1)
INSERT INTO @GroupRights VALUES(3, 5)
INSERT INTO @GroupRights VALUES(4, 1)

SELECT * FROM @GroupRights
SELECT * FROM @UserRights

;WITH CTE AS
(
 SELECT 
 G.ID,
 G.RightID
 FROM
  @GroupRights G 
  ),
 CTE1 AS
 (
   SELECT 
          U.Id,
          U.RightId
   FROM
          @UserRights U
 )
 SELECT 
       CASE WHEN CTE.Id = CTE1.Id THEN CTE1.Id ELSE CTE.Id END AS Id,
       CASe WHEN CTE.Id = CTE1.Id THEN CTE1.RightID ELSE CTE.RightId END AS         RightId
       FROM CTE LEFT JOIN CTE1 ON CTE1.Id = CTE.Id