SQL条件JOIN

时间:2010-08-13 17:44:39

标签: sql sql-server sql-server-2005 tsql

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

我目前有以下存储过程来通过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?

4 个答案:

答案 0 :(得分:4)

我的第一个建议是从员工表中删除部门ID。将所有记录插入Departments表中的员工。

然后这是一个简单的内部联接。

当然,永远不要在生产代码中使用select *。

答案 1 :(得分: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

UNION必须删除重复项 - 如果您知道永远不会重复,请将UNION更改为UNION ALL

被称为“摘要”的CTE没有提供任何性能优势,只是简写。

答案 2 :(得分: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。

答案 3 :(得分:0)

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

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

您可以查看此帖子以将IN转换为WHERE EXISTS

Changing IN to EXISTS in SQL