【问题标题】:SQL query in a query查询中的 SQL 查询
【发布时间】:2013-05-30 16:00:23
【问题描述】:

[删除公司机密信息或图形]

我的数据库中有这种结构。我需要建立一个员工姓名列表,然后是他们的部门和办公室的名称。到目前为止,我已经来到了这个查询:

ALTER PROCEDURE FilterEmpList
    @empName nvarchar(250) = null,
    @empDepID int = null,
    @empOfficeID int = null,
    @empPosID int = null    
AS 
BEGIN
SELECT 
    E.emp_id AS 'emp_id',
    E.emp_name AS 'emp_name',      
    (SELECT pos_name FROM Positions WHERE pos_id=EP.pos_id) AS 'pos_name',
    (SELECT dep_name FROM Departments WHERE dep_id=OS.dep_id) AS 'dep_name',
    (SELECT office_name FROM Offices WHERE office_id=OS.office_id) AS 'office_name'
FROM 
    Org_Structure OS INNER JOIN (Emp_Positions EP INNER JOIN Employees E ON EP.emp_id=E.emp_id) ON OS.chain_id=EP.chain_id      
WHERE 
    (E.emp_name LIKE '%'+@empName+'%' OR @empName IS NULL)
    AND
    (OS.dep_id = @empDepID OR @empDepID IS NULL)
    AND
    (OS.office_id = @empOfficeID OR @empOfficeID IS NULL)
    AND
    (EP.pos_id = @empPosID OR @empPosID IS NULL)
END

当我以这种方式执行 exec FilterEmpList 时,出现错误:Invalid object name 'EP'。

【问题讨论】:

    标签: sql-server tsql inner-join invalid-object-name


    【解决方案1】:

    您不能在其范围之外引用内联选择表。 我建议使用自然连接,例如:

    Select Emp_ID,Emp_Name,Dep_Name,Office_Name,Pos_Name
    From Employees e
    Join Emp_positions ep on ep.Emp_ID = e.Emp_ID
    Join Org_Structue os on os.Chain_ID = ep.Chain_ID
    Join Departments d on d.Dep_ID = os.Dep_ID
    Join Offices o on o.office_ID = os.Office_ID
    Join Positions p on p.Pos_ID = os.Pos_ID
    Where (E.emp_name LIKE '%'+@empName+'%' OR @empName IS NULL)
        AND
        (OS.dep_id = @empDepID OR @empDepID IS NULL)
        AND
        (OS.office_id = @empOfficeID OR @empOfficeID IS NULL)
        AND
        (EP.pos_id = @empPosID OR @empPosID IS NULL)
    

    【讨论】:

      【解决方案2】:

      您的内部联接/联接存在问题。在看到查询和 ERD 之后,我假设您正在寻找这个,

      ALTER PROCEDURE FilterEmpList
          @empName nvarchar(250) = null,
          @empDepID int = null,
          @empOfficeID int = null,
          @empPosID int = null    
      AS 
      BEGIN
      SELECT 
          E.emp_id AS 'emp_id',
          E.emp_name AS 'emp_name',      
          (SELECT pos_name FROM Positions WHERE pos_id=EP.pos_id) AS 'pos_name',
          (SELECT dep_name FROM Departments WHERE dep_id=OS.dep_id) AS 'dep_name',
          (SELECT office_name FROM Offices WHERE office_id=OS.office_id) AS 'office_name'
      FROM 
          Org_Structure OS 
      INNER JOIN Emp_Positions EP ON EP.ChainId ==  Emp_Positions.ChainId
      INNER JOIN Employees E ON EP.emp_id=E.emp_id      
      WHERE 
          (E.emp_name LIKE '%'+@empName+'%' OR @empName IS NULL)
          AND
          (OS.dep_id = @empDepID OR @empDepID IS NULL)
          AND
          (OS.office_id = @empOfficeID OR @empOfficeID IS NULL)
          AND
          (EP.pos_id = @empPosID OR @empPosID IS NULL)
      END
      

      同时尝试使别名更易读。

      谢谢

      【讨论】:

        【解决方案3】:

        这可能对你有帮助 -

        ALTER PROCEDURE dbo.FilterEmpList
            @empName nvarchar(250) = null,
            @empDepID int = null,
            @empOfficeID int = null,
            @empPosID int = null    
        AS 
        BEGIN
        
            SELECT 
                E.emp_id,
                E.emp_name,      
                p.pos_name,
                d.dep_name,
                o.office_name
            FROM dbo.Org_Structure OS 
            JOIN dbo.Emp_Positions EP ON OS.chain_id=EP.chain_id  
            /*LEFT*/ JOIN dbo.Employees E ON EP.emp_id=E.emp_id 
            /*LEFT*/ JOIN dbo.Positions p ON p.pos_id=EP.pos_id
            /*LEFT*/ JOIN dbo.Departments d ON d.dep_id=OS.dep_id
            JOIN dbo.Offices o ON o.office_id=OS.office_id  
            WHERE (
                      E.emp_name LIKE '%'+@empName+'%' 
                    OR 
                      @empName IS NULL
                )
                AND OS.dep_id = ISNULL(@empDepID, OS.dep_id)
                AND OS.office_id = ISNULL(@empOfficeID, OS.office_id)
                AND EP.pos_id = ISNULL(@empPosID, EP.pos_id)
        
        END
        

        【讨论】:

          【解决方案4】:

          您的查询将失败,因为您尝试将 EP 加入 Org_structure 表,但此 EP 在括号内。这是不允许的。试试下面

          ALTER PROCEDURE FilterEmpList
          @empName nvarchar(250) = null,
          @empDepID int = null,
          @empOfficeID int = null,
          @empPosID int = null    
           AS 
            BEGIN
           SELECT 
           E.emp_id AS 'emp_id',
           E.emp_name AS 'emp_name',      
          (SELECT pos_name FROM Positions WHERE pos_id=EP.pos_id) AS 'pos_name',
          (SELECT dep_name FROM Departments WHERE dep_id=OS.dep_id) AS 'dep_name',
          (SELECT office_name FROM Offices WHERE office_id=OS.office_id) AS 'office_name'
          FROM 
            Org_Structure OS 
            INNER JOIN Emp_Positions EP ON OS.chain_id=EP.chain_id 
            INNER JOIN Employees E ON EP.emp_id=E.emp_id     
          WHERE 
           (E.emp_name LIKE '%'+@empName+'%' OR @empName IS NULL)
          AND
           (OS.dep_id = @empDepID OR @empDepID IS NULL)
          AND
           (OS.office_id = @empOfficeID OR @empOfficeID IS NULL)
          AND
           (EP.pos_id = @empPosID OR @empPosID IS NULL)
          END
          

          【讨论】:

            【解决方案5】:

            您好,您检查过您的表 EMP_Positions 是否存在?

            【讨论】:

              【解决方案6】:

              我认为你们中的一些代码放错了位置。试试这个...

              SELECT 
                  E.emp_id AS 'emp_id',
                  E.emp_name AS 'emp_name',      
                  P.pos_name  AS 'pos_name',
                  D.dep_name AS 'dep_name',
                  O.office_name AS 'office_name'
              FROM 
                  Org_Structure OS 
                  INNER JOIN Emp_Positions EP ON OS.chain_id=EP.chain_id 
                  INNER JOIN Employees E ON EP.emp_id=E.emp_id    
                  LEFT JOIN Positions P ON P.pos_id=EP.pos_id
                  LEFT JOIN Departments D ON D.dep_id=OS.dep_id
                  LEFT JOIN Offices O ON O.office_id=OS.office_id
              WHERE 
                  (E.emp_name LIKE '%'+@empName+'%' OR @empName IS NULL)
                  AND
                  (OS.dep_id = @empDepID OR @empDepID IS NULL)
                  AND
                  (COALESCE(O.office_id,@empOfficeID ) = @empOfficeID OR @empOfficeID IS NULL)
                  AND
                  (EP.pos_id = @empPosID OR @empPosID IS NULL)
              

              【讨论】:

              • @Vladimir 我已将子查询移出 SELECT,因为其中 oen 中对 EP 的引用可能是问题
              • @Vladimir 我修改以展示如何使用合并来保留 NULL - 您可能希望在 SELECT 中添加进一步的合并以放置“无办公室”或缺失的内容,具体取决于你想要达到的目标
              • @Devart 的 ISNULL 子句比我的更干净——我推荐那些
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-09-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多