这是我最终使用的解决方案。我将 JoinMode 添加到 Group 表中,该表的有效值分别为包含和排除的“IN”和“EX”。每个人似乎都同意这是这样做的方法。我认为这会使连接表的内容相当混乱,但希望这是最不坏的解决方案。
在查询中,我执行 CROSS JOIN 以创建所有可能的关系,然后根据连接表值是否存在,将不需要的关系删除到 WHERE 约束中。
DECLARE @User TABLE
(UserID int
,UserName varchar(16))
INSERT INTO @User VALUES (1, 'John')
INSERT INTO @User VALUES (2, 'Jim')
INSERT INTO @User VALUES (3, 'Bob')
INSERT INTO @User VALUES (4, 'George')
DECLARE @Group TABLE
(GroupID int
,GroupName varchar(16)
,JoinMode char(2))
INSERT INTO @Group VALUES (1, 'Nobody', 'IN')
INSERT INTO @Group VALUES (2, 'Only John', 'IN')
INSERT INTO @Group VALUES (3, 'Jim & Bob', 'IN')
INSERT INTO @Group VALUES (4, 'Not John', 'EX')
INSERT INTO @Group VALUES (5, 'Everybody', 'EX')
DECLARE @UserGroup TABLE
(UserID int
,GroupID int)
INSERT INTO @UserGroup VALUES (1, 2) -- Only John
INSERT INTO @UserGroup VALUES (2, 3) -- Jim & Bob
INSERT INTO @UserGroup VALUES (3, 3) -- Jim & Bob
INSERT INTO @UserGroup VALUES (1, 4) -- Not John
SELECT
g.GroupName
,u.UserName
FROM
(
@User u
CROSS JOIN
@Group g
)
LEFT OUTER JOIN
@UserGroup ug ON (
u.UserID = ug.UserID
AND g.GroupID = ug.GroupID
)
WHERE
(
g.JoinMode = 'IN'
AND ug.UserID IS NOT NULL
)
OR (
g.JoinMode = 'EX'
AND ug.UserID IS NULL
)
ORDER BY
g.GroupID
,u.UserID
如果您发现这种方法有任何问题,或者您有更好的方法,请告诉我。