代码之家  ›  专栏  ›  技术社区  ›  Alfero Chingono

SQL条件联接

  •  1
  • Alfero Chingono  · 技术社区  · 14 年前

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

    我当前有以下存储过程按部门ID检索员工:

    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
    

    如何优化此存储过程并可能使用联接?

    4 回复  |  直到 14 年前
        1
  •  1
  •   Shlomo    14 年前
       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逻辑。

        2
  •  4
  •   HLGEM    14 年前

    我给您的第一个建议是从employee表中删除department Id。将所有记录插入部门表中的员工。

    当然,不要在产品代码中使用select*。

        3
  •  4
  •   OMG Ponies    14 年前

    以下是我对你的质疑的回复:

    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 ALL .

    名为“summary”的CTE并没有提供任何性能优势,它只是一种简写。

        4
  •  0
  •   Community CDub    8 年前

    我建议你换个房间 IN 查询中使用的子句 WHERE EXISTS .

    如果您正在使用 在查询中,这意味着您没有从表上定义的索引中获益,查询将执行一次完整的表扫描,这将影响查询性能。

    您可以检查此线程以转换 哪里存在 :

    Changing IN to EXISTS in SQL