避免在WHERE子句中两次引用表

时间:2016-03-22 15:09:10

标签: sql-server

以下是SQL Server 2005中数据库的简化版本。我需要根据业务部门选择员工。每位员工都有家庭部门,家长部门和访问部门。根据部门,可以找到业务部门。

  • 对于员工,如果HomeDeptID = ParentDeptID,那么 VisitingDeptID应该存在@SearchBusinessUnitCD。
  • 如果HomeDeptID<> ParentDeptID,然后@SearchBusinessUnitCD应该是 出现在ParentDeptID上。

以下查询工作正常。但是它已经在#DepartmentBusinesses表上扫描了两次。是否可以通过将表#DepartmentBusinesses用作CASE语句或类似方法来使用表#DepartmentBusinesses?

DECLARE @SearchBusinessUnitCD CHAR(3)
SET @SearchBusinessUnitCD = 'B'

--IF HomeDeptID = ParentDeptID, then @SearchBusinessUnitCD should be present for the VisitingDeptID
--IF HomeDeptID <> ParentDeptID, then @SearchBusinessUnitCD should be present for the ParentDeptID

CREATE TABLE #DepartmentBusinesses (DeptID INT, BusinessUnitCD CHAR(3))
INSERT INTO #DepartmentBusinesses
    SELECT 1, 'A' UNION ALL 
    SELECT 2, 'B' 

CREATE NONCLUSTERED INDEX IX_DepartmentBusinesses_DeptIDBusinessUnitCD ON #DepartmentBusinesses (DeptID,BusinessUnitCD)

DECLARE @Employees TABLE (EmpID INT, HomeDeptID INT, ParentDeptID INT, VisitingDeptID INT)
INSERT INTO @Employees 
    SELECT 1, 1, 1, 2 UNION ALL
    SELECT 2, 2, 1, 3

SELECT * 
FROM @Employees
WHERE
    (
            HomeDeptID = ParentDeptID
        AND
            EXISTS (
                SELECT 1
                FROM #DepartmentBusinesses
                WHERE DeptID = VisitingDeptID
                    AND BusinessUnitCD = @SearchBusinessUnitCD)
            )
    OR 
    (
            HomeDeptID <> ParentDeptID
        AND
            EXISTS (
                SELECT 1
                FROM #DepartmentBusinesses
                WHERE DeptID = ParentDeptID
                    AND BusinessUnitCD = @SearchBusinessUnitCD
            )
    )

DROP TABLE #DepartmentBusinesses

计划

enter image description here

2 个答案:

答案 0 :(得分:4)

SELECT * 
FROM @Employees e
WHERE EXISTS (
        SELECT 1
        FROM #DepartmentBusinesses t
        WHERE t.BusinessUnitCD = @SearchBusinessUnitCD
            AND (
                (e.HomeDeptID = e.ParentDeptID AND t.DeptID = e.VisitingDeptID)
                OR
                (e.HomeDeptID != e.ParentDeptID AND t.DeptID = e.ParentDeptID)
            )
    )

答案 1 :(得分:2)

你可以尝试一下:

SELECT e.* 
FROM @Employees AS e
INNER JOIN #DepartmentBusinesses AS d 
  ON (d.DeptID = e.VisitingDeptID AND e.HomeDeptID = e.ParentDeptID) OR
     (d.DeptID = e.ParentDeptID AND e.HomeDeptID <> e.ParentDeptID)
WHERE d.BusinessUnitCD = @SearchBusinessUnitCD