2

我们有一个groupuser permission表如下:

Group (group_id,name)
01 | G1
02 | G2
03 | G3
04 | G4

UserPermission (userid,group_id,active)
User1 | 01 | 1
User1 | 02 | 1
User2 | 01 | 1
User2 | 02 | 1
User2 | 03 | 1
User2 | 04 | 1
..
UserN | xx | 1

每个User都拥有一个Group的权限。
但是 UserPermission 表中缺少某些用户的某些权限。

问题是为表中存在的所有用户插入那些缺少的组权限条目 UserPermission

所以我想出的查询是(粗略的)

 insert into UserPermission 
         select distinct userid, '03', 1 from UserPermission  
         where userid not in (
               select userid from UserPermission where group_id = '03'
         )

这是因为Group 03..
其他组的用户缺少插入权限。

有没有更好的方法来编写上述查询。如何优化?

4

4 回答 4

3

在我的解决方案中,我从表GroupUserPermission仅唯一用户 ID)中获取笛卡尔积。然后将两个表的乘积连接到表上UserPermissionLEFT JOIN前提是它在两列上匹配:Group_IDuserID。任何不满足条件的记录都将NULL在 的列上具有值UserPermission。而这些值就是UserPermission表中的缺失值。

这也将为所有用户填充所有缺失的权限

INSERT INTO UserPermission(userID, group_ID, active)
SELECT  b.userID, a.Group_ID, 1
FROM    [Group] a
        CROSS JOIN (SELECT DISTINCT userID FROM UserPermission) b
        LEFT JOIN UserPermission c
            ON a.Group_ID = c.Group_ID AND
                b.userID = c.UserID
WHERE   c.Group_ID IS NULL

但是如果你只想插入特定Group_ID的,那么你需要额外的条件。

INSERT INTO UserPermission(userID, group_ID, active)
SELECT  b.userID, a.Group_ID, 1
FROM    [Group] a
        CROSS JOIN (SELECT DISTINCT userID FROM UserPermission) b
        LEFT JOIN UserPermission c
            ON a.Group_ID = c.Group_ID AND
                b.userID = c.UserID
WHERE   c.Group_ID IS NULL AND
        a.Group_ID = 3
        -- or change it to IN clause
        -- if you have more Group_ID to include
        -- a.Group_ID IN (3,4)
于 2013-04-01T15:30:47.250 回答
1

不存在通常比不存在更好。

insert into UserPermission
select disinct userid, '03', 1
from UserPermission
where not exists 
(select *
from UserPermission
where group_id = '03')

另一种方法是使用“in”而不是“not in”

insert into UserPermission
select disinct userid, '03', 1
from UserPermission
where user_id in 
(select user_id from UserPermission
except 
select user_id from UserPermission
where group_id = '03')
于 2013-04-01T15:33:24.273 回答
1

这是一种方法:

 with toinsert as (
    select userid, '03' as UserPermission
    from UserPermission up
    group by userId
    having sum9case when userPermission = '03' then 1 else 0 end) = 0
 )
 insert into UpserPermission
    select userid, UserPermission
    from toinsert;

我已将插入列表分解为 CTE。您也可以将其作为子查询执行:

insert into UserPermission
    select userid, '03'
    from UserPermission
    group by userid
    having sum(case when userpermission = '03' then 1 else 0 end) = 0
于 2013-04-01T15:45:30.370 回答
1

另一种可能的解决方案是使用新的 MERGE 语句。根据我的经验,MERGE 表现非常出色。

merge UserPermission target
using (
    -- Assuming u.userid and g.group_id are unique in their tables
    select u.userid, g.group_id
    from [User] u
    cross join [Group] g
) source on source.userid = target.userid and source.group_id = target.group_id
when not matched then
    insert (userid, group_id, active)
    values (source.userid, source.group_id, 1);
于 2013-04-01T17:42:21.280 回答