(可选)强制LEFT到INNER JOIN

时间:2017-09-30 23:27:41

标签: sql-server tsql

问题

我的问题从我的上一个(Mutually Exclusive Queries)发展而来。我的查询已经发展。我需要获得组织中的所有用户。如果我被分配到某个部门,我可以选择过滤该列表,只对我所在部门的用户进行过滤。你能帮忙吗?

方法

我试图在我的LEFT JOIN条款中强加INNER JOIN EXISTS WHERE CREATE TABLE #OrganizationsUsers ( OrganizationId int, UserId int, PRIMARY KEY (OrganizationId, UserId) ); CREATE TABLE #DepartmentsUsers ( DepartmentId int, UserId int, PRIMARY KEY (DepartmentId, UserId) ); INSERT #OrganizationsUsers VALUES (1, 33), (1138, 421), (1138, 1), (1138, 2), (1138, 3), (1138, 4), (1138, 5); INSERT #DepartmentsUsers VALUES (11, 421), (11, 1), (11, 2), (12, 3), (12, 4); DECLARE @OrganizationId int = 1138; DECLARE @PrincipalUserId int = 421; SELECT ou.UserId FROM #OrganizationsUsers AS ou LEFT JOIN ( SELECT du.UserId FROM #DepartmentsUsers AS du JOIN #DepartmentsUsers AS du2 ON du.DepartmentId = du2.DepartmentId WHERE du2.UserId = @PrincipalUserId ) AS lj ON ou.UserId = lj.UserId WHERE ou.OrganizationId = @OrganizationId AND ((EXISTS (SELECT * FROM #DepartmentsUsers WHERE UserId = @PrincipalUserId AND OrganizationId = @OrganizationId) AND lj.UserId IS NOT NULL) OR lj.UserId IS NULL); DROP TABLE #OrganizationsUsers; DROP TABLE #DepartmentsUsers; 。你觉得怎么样?

实施例

prediction

预期产出

当主体不在DeparmentsUsers表中时:
用户ID
1
2
3
4
5
421

当委托人被分配到部门11时:
用户ID
1
2
421

当委托人被分配到部门12时:
用户ID
3
4
421

1 个答案:

答案 0 :(得分:0)

诀窍是有一个完整的WHERE子句,可以在分配给部门的用户之间切换。我需要EXISTS ()NOT EXISTS()LEFT JOIN列为NULLNOT NULL

CREATE TABLE #OrganizationsUsers (
  OrganizationId int,
  UserId int,
  PRIMARY KEY (OrganizationId, UserId)
);

CREATE TABLE #DepartmentsUsers (
  DepartmentId int,
  UserId int,
  PRIMARY KEY (DepartmentId, UserId)
);

INSERT #OrganizationsUsers VALUES
(1, 33),
(1138, 421),
(1138, 1),
(1138, 2),
(1138, 3),
(1138, 4),
(1138, 5);

INSERT #DepartmentsUsers VALUES
--(12, 421),
(11, 1),
(11, 2),
(12, 3),
(12, 4);

DECLARE @OrganizationId int = 1138;
DECLARE @PrincipalUserId int = 421;

SELECT ou.UserId
FROM #OrganizationsUsers AS ou
LEFT JOIN (
  SELECT du.UserId
  FROM #DepartmentsUsers AS du
  JOIN #DepartmentsUsers AS du2 ON du.DepartmentId = du2.DepartmentId
  WHERE du2.UserId = @PrincipalUserId
) AS lj ON ou.UserId = lj.UserId
WHERE ou.OrganizationId = @OrganizationId
  AND ((EXISTS (SELECT * FROM #DepartmentsUsers WHERE UserId = @PrincipalUserId AND OrganizationId = @OrganizationId) AND lj.UserId IS NOT NULL)
    OR (NOT EXISTS (SELECT * FROM #DepartmentsUsers WHERE UserId = @PrincipalUserId AND OrganizationId = @OrganizationId) AND lj.UserId IS NULL));

DROP TABLE #OrganizationsUsers;
DROP TABLE #DepartmentsUsers;