【问题标题】:LEFT OUTER JOIN with INNER JOIN左外连接和内连接
【发布时间】:2013-11-22 18:48:19
【问题描述】:

我有一张学生桌。 和一张教师表。

部分学生(不是全部)将有一位老师分配给他们。 这在第三张表中进行控制,通过 studentID 和teacherID 将这些学生与他们的老师进行匹配

我需要 SQL 做的是将LEFT OUTER JOIN 放到第三张表上,然后将INNER JOINED 放到老师的桌子上(因为不是所有的学生都会出现在第三张表中,但是任何出现在第三张表中的老师第三张表将出现在教师表中)。

我希望获得所有学生姓名和教师姓名的结果,以及他们被分配的位置(如果不是,则为 null)。

我目前的样子是这样的,它基本上是作为一个完整的 INNER JOIN 运行的,并且不会给我没有分配老师的学生:

SELECT firstname, teacherlastName
FROM tblstudents 

left outer join [tblStudentRakazot] 
ON tblstudents.studentid = [tblStudentRakazot].studentID 

INNER JOIN tblteachers 
ON [tblStudentRakazot].teacherid = tblteachers.teacherID

有人可以在这里给我指点吗?我尝试放置括号,但没有看到,以提供帮助。

谢谢!

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您不使用INNER JOIN,而只使用另一个LEFT JOIN

    将 tblStudents 视为您的基地。您想获取所有这些,而不是过滤掉任何东西,并且只附加可选信息。 使用第一个左连接,您附加了第一个信息
    学生 -> 教师作业
    TeacherAssignment 可以为空或不为空。 现在您只需附加另一个信息 - 老师的全名来自tblTeachers
    学生 -> TeacherAssignnent -> TeacherName
    使用另一个LEFT JOIN 执行此操作。在可能的情况下附加信息,即 TeacherAssignment 不为空的地方。 这将忽略 TeacherAssignment 无论如何为空的行。

    【讨论】:

      【解决方案2】:
      SELECT firstname, teacherlastName
      FROM tblstudents 
      left outer join
      ( select * from
       [tblStudentRakazot] A INNER JOIN tblteachers B 
      ON A.teacherid = B.teacherID)AS C
      ON tblstudents.studentid = C.studentID 
      

      【讨论】:

      • 谢谢你,你的回答很有帮助,因为它使我能够在内部 SELECT 上使用 WHERE 子句
      【解决方案3】:

      您可以将 INNER JOIN 移动到子查询中

      SELECT  firstname, teacherlastName
      FROM    tblstudents 
              LEFT OUTER JOIN
              (   SELECT  [tblStudentRakazot].studentID, tblTeachers.teacherlastName
                  FROM    [tblStudentRakazot]
                          INNER JOIN tblteachers 
                              ON [tblStudentRakazot].teacherid = tblteachers.teacherID
              ) teachers
                  ON tblstudents.studentid = teachers.studentID 
      

      另一种选择是使用更复杂的 where 子句。

      SELECT  firstname, teacherlastName
      FROM    tblstudents 
              LEFT JOIN [tblStudentRakazot] 
                  ON tblstudents.studentid = [tblStudentRakazot].studentID 
              LEFT JOIN tblteachers 
                  ON [tblStudentRakazot].teacherid = tblteachers.teacherID
      WHERE   [tblStudentRakazot] IS NULL
      OR      tblteachers.teacherID IS NOT NULL
      

      但是,SQL Server 非常擅长在需要的地方从子查询中传播谓词,因此我更倾向于第一种方法,以提高可读性和效率。

      编辑

      我没有正确阅读问题,我以为您不想要tblStudentRakazot 中的teacherID 为NULL 的记录。如果这不是问题,那么您可以简单地使用两个 LEFT JOINS,而不使用上面的 where 子句:

      SELECT  firstname, teacherlastName
      FROM    tblstudents 
              LEFT JOIN [tblStudentRakazot] 
                  ON tblstudents.studentid = [tblStudentRakazot].studentID 
              LEFT JOIN tblteachers 
                  ON [tblStudentRakazot].teacherid = tblteachers.teacherID
      

      【讨论】:

      • 我开始怀疑我是否误解了什么:他只想要学生和分配的老师,或者为老师为 null。在您的第二个查询中根本不需要任何 WHERE 部分...
      • @KekuSemau 我没有正确阅读问题,我认为 OP 不想要 tblStudentRakazot 中的teacherID 为 NULL 的记录,这就是为什么我认为需要 where 子句的原因,你是对的,它不是必需的。
      【解决方案4】:
      SELECT b.student_firstname, teacherlastName
      FROM thirdtable a 
      left join studenttbl b on a.studentid = b.studentid
      left join teachertbl b on a.teacherid = b.teacherid
      

      如果您确定教师表中的某些数据是唯一的,您始终可以使用外连接。它将给出与内部连接相同的结果。

      【讨论】:

        【解决方案5】:

        您不能像@GarethD 示例那样使用子查询。

        SELECT firstname, teacherlastName
        FROM tblstudents
        LEFT OUTER JOIN [tblStudentRakazot]
            INNER JOIN tblteachers
                ON [tblStudentRakazot].teacherid = tblteachers.teacherID
            ON tblstudents.studentid = [tblStudentRakazot].studentID
        

        但是,当更深入地查看此查询的执行计划时,使用子查询的查询可能是等效的。

        【讨论】:

          猜你喜欢
          • 2015-01-11
          • 1970-01-01
          • 1970-01-01
          • 2011-10-01
          • 1970-01-01
          • 2017-08-15
          • 2015-03-04
          • 2018-07-31
          • 1970-01-01
          相关资源
          最近更新 更多