我有3张桌子,
room (room_no
)
room_no_access (room_no, user_id
)
user (user_id
)
如果用户在room_no_access
表格中记录room_no
和user_id
,则该用户无法访问上述会议室。
我们假设我是user
表中的用户。现在我需要的是让与我共享至少一个公共房间访问权限的用户。
如何编写SQL来完成这项工作?如果没有循环,那就更好了。
示例:
rooms
room_1,
room_2,
room_3,
users
1,
2,
3,
4,
rooms_no_access
[room_1, 4],
[room_2, 3].
[room_3, 3],
[room_1, 3],
如果我是用户4 - >我可以访问room_2,room_3 那么谁是可以访问room_2或room_3的其他用户 它们是 - > 1,2
答案 0 :(得分:0)
这是一种回到前面的方式,因为你可以容纳人们无法访问的房间,我们真的想要人们可以访问的房间。
我创建了一些测试数据:
--Test data
DECLARE @room TABLE (room_no INT);
INSERT INTO @room SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3;
DECLARE @user TABLE ([user_id] INT);
INSERT INTO @user SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3;
DECLARE @room_no_access TABLE (room_no INT, [user_id] INT);
INSERT INTO @room_no_access SELECT 1, 1;
INSERT INTO @room_no_access SELECT 3, 2;
INSERT INTO @room_no_access SELECT 1, 3;
INSERT INTO @room_no_access SELECT 2, 3;
INSERT INTO @room_no_access SELECT 3, 3;
...然后提出了这个问题:
--For each user find users with common access
--First find which rooms each user can access
WITH room_access AS (
SELECT
r.room_no,
u.[user_id]
FROM
@room r
CROSS JOIN @user u
LEFT JOIN @room_no_access rn ON rn.room_no = r.room_no AND rn.[user_id] = u.[user_id]
WHERE
rn.[user_id] IS NULL)
SELECT DISTINCT
u.[user_id],
sa.[user_id] AS shared_access_user
FROM
@user u
LEFT JOIN room_access ra ON ra.[user_id] = u.[user_id]
LEFT JOIN room_access sa ON sa.room_no = ra.room_no
WHERE
sa.[user_id] != u.[user_id]; --Ignore self match
这对工作来说有点啰嗦,但很容易理解。
结果是:
user_id shared_access_user
1 2
2 1
因为在我的数据中,user_id#1和#2共享对2号房间的访问权限,但是user_id#3无法访问任何房间。
我正在为数据库中的每个用户返回结果,但您可以将其过滤为仅返回指定用户的结果吗?
答案 1 :(得分:0)
试试这个:
select distinct [user_id] from (
--all rooms that can be accessed by at least one user
select room_no, [USER_ID] from room cross join [user]
except
select room_no, [USER_ID] from room_no_access
) a where room_no in (
-- rooms that I have access to
select room_no from room
except
select room_no from room_no_access where [USER_ID] = /*my_user_id*/
)
答案 2 :(得分:0)
此选择与您共享访问权限的用户及其共享的房间。
set @you = 1;
select
others_access.user_id,
others_access.room_no
from
(select room_no, @you as user_id
from room r
/* rooms that you have access */
where not exists (
select * from room_no_access rna
where rna.room_no = r.room_no
and rna.user_id = @you)) you_access
join
/* rooms that others have access */
(select room_no, u.user_id
from room r cross join user u
where u.user_id <> @you
and not exists (
select * from room_no_access rna
where rna.room_no = r.room_no
and rna.user_id = u.user_id)) others_access
on you_access.room_no = others_access.room_no;