我们有一个group
和user 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
每个用户都拥有群组的权限 但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
的用户缺少的插入权限
与其他群体类似。
是否有更好的方法来编写上述查询。如何优化?
答案 0 :(得分:3)
在我的解决方案中,我从表Group
和UserPermission
(唯一的用户ID )获取了笛卡尔积。然后,使用UserPermission
将两个表的产品连接回LEFT JOIN
表,前提是它匹配两列:Group_ID
和userID
。任何不满足条件的记录在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)
答案 1 :(得分: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')
答案 2 :(得分: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
答案 3 :(得分: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);