2010-08-13 73 views
1

我有三个表'员工','部门'和'EmployeesInDepartments' '员工'表引用'部门'表(每个员工必须有一个DepartmentId)。但是,通过向“EmployeeInDepartments”表中添加条目(EmployeeId和DepartmentId),员工可以存在于多个部门中。SQL有条件JOIN

目前,我有以下存储过程按DepartmentID检索员工:

CREATE PROCEDURE dbo.CollectEmployeesByDepartmentId 
    (
    @DepartmentId int, 
    @IsDeleted bit 
    ) 
AS 
BEGIN 
     SELECT Employees.* 
     FROM  Employees 
     WHERE ((Employees.IsDeleted = @IsDeleted) 
      AND ((Employees.DepartmentId = @DepartmentId) 
       OR (Employees.EmployeeId IN (SELECT EmployeesInDepartments.EmployeeId 
             FROM EmployeesInDepartments 
             WHERE (EmployeesInDepartments.DepartmentId = @DepartmentId) 
             ) 
        ) 
       ) 
     ) 
END 

如何优化这个存储过程,并可能使用JOINS?

回答

1
SELECT E.* 
    FROM Employees E 
     Left Join EmployeesInDepartments EID ON E.EmployeeId = EID.EmployeeId 
     And E.DepartmentId <> @DepartmentId 

    WHERE E.IsDeleted = @IsDeleted 
     And 
     ( 
     E.DepartmentId = @DepartmentId 
     Or (EID.DepartmentId = @DepartmentId) 
    ) 

编辑包含IsDeleted逻辑。 我同意其他一些答案,你的设计应该可能改变。但是这个查询应该这样做。如果您在EmployeesInDepartments中有重复项,则可以将其更改为Select Distinct。

+0

出于好奇,JOIN有没有性能好处? – 2010-08-13 18:24:38

+0

虽然这没有很多选票,但这是我正在寻找的答案。 – 2010-08-27 16:58:17

4

我第一次向你推荐的是从员工表中删除部门ID。将所有记录插入到Departments表中的员工。

然后它是一个简单的内部连接。

当然,从来没有在生产代码中使用select *。

+0

感谢SELECT *建议。设计上的改变已经提出,但尚未获得批准。转换当前数据可能需要一些工作。 – 2010-08-13 18:17:01

4

这是你的查询我重新写:

WITH summary AS (
    SELECT e.* 
    FROM EMPLOYEES e 
    WHERE e.isdeleted = @IsDeleted 
     AND e.parentid = 0) 
SELECT a.* 
    FROM summary a 
WHERE a.departmentid = @DepartmentId 
UNION 
SELECT b.* 
    FROM summary b 
    JOIN EMPLOYEESINDEPARTMENTS ed ON ed.employeeid = b.employeeid 
           AND ed.departmentid = @DepartmentId 

欧盟有必要删除重复的 - 如果你知道再也不会有重复,改变UNIONUNION ALL

称为“摘要”的CTE不提供任何性能优势,它只是速记。

+0

感谢UNION建议。 – 2010-08-13 18:17:33

0

我建议你将查询中使用的IN子句更改为WHERE EXISTS

如果您在查询中使用IN,这意味着您没有对表中定义的索引进行处理,查询将执行影响查询性能的完整表扫描。

您可以检查此线程转换INWHERE EXISTS

Changing IN to EXISTS in SQL

+0

-1它们在SQL Server中的处理方式完全相同http://sqlinthewild.co.za/index.php/2009/08/17/exists-vs-in/ – 2010-08-13 21:42:01