SQL Join:两个表之间的选择是否仍然加入?

时间:2014-11-05 17:57:38

标签: mysql sql oracle join

当我读到SQL中的内部或外部联接时,所有示例和描述都是关于2个表的连接。如果查询中有两个以上的表怎么办?这仍然被认为是一个加入?

我认为内连接仍然有意义,即使它在多个表之间;但我不确定外连接在两个以上的表之间是否有意义。

有人可以澄清这个问题吗?

3 个答案:

答案 0 :(得分:2)

内部连接和外部连接非常合理,可以使用2个以上的表格 内部联接强制结果仅显示包含您所加入的行的数据,而外部联接则显示所有数据,无论如何。

让我们说你想加入4张桌子......

select * from testtable
inner join testable2 on col1 = othercolumn
inner join testable3 on col2 = othercolumn
leftjoin testable4 on col3 = othercolumn

在这种情况下,它只返回内部联接中存在的结果,但结果不必存在于外部/左侧联接中。你正在强迫测试表2& 3要对你加入的内容有一个值..它不能为空。

左连接不关心值是否为null,并且无论如何都会显示结果。 我希望这有助于一些...基本上..如果你内部加入一个值,它可能是null,那么整个查询将显示为空。这是您将使用outter join的场景..您不是强制值存在。

答案 1 :(得分:1)

大多数连接示例都包含两个表。但是,可以在任意数量的表上完成连接。

您可以阅读有关整个互联网的联接的更多信息,但您可能希望从以下开始:

http://www.w3schools.com/sql/sql_join.asp

http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/

w3schools文章首先说的是:

  

SQL连接用于组合来自两个或多个表的行。

这不是完全正确的,因为你甚至可以在桌子上加入表格!

考虑:

Employees
-----
EmployeeId
ManagerId
EmployeeName

如果您想查找特定经理的员工,可以写成:

select manager.EmployeeName, subordinates.*
from employees manager
inner join employees subordinates on manager.employeeId = subordinates.managerId

对于多个表连接,请考虑:

Employees
----
EmployeeId
ManagerId
EmployeeName

Departments
----
DepartmentId
DepartmentName

EmployeeDepartments
----
DepartmentId
EmployeeId

在这种情况下,如果您想查找员工5所属的所有部门名称,您可以这样做:

 select d.DepartmentName
 from employees e
 inner join employeeDepartments ed on e.employeeId = ed.employeeId
 inner join departments d on ed.departmentId = d.departmentId
 where e.employeeId = 5

TLDR; - 是的,包括超过2个表仍被视为加入

答案 2 :(得分:1)

每个join子句(逻辑上)在两个虚拟表之间,但虚拟表本身可以定义为其他表上的连接。

所以在下面的例子中

SELECT Foo
FROM   A
       INNER JOIN B
               ON A.X = B.X
       INNER JOIN C
               ON C.Y = A.Y
                  AND C.Z = B.Z 

可以认为逻辑A连接到B然后虚拟表(A x B)连接到C.因此,最终ON子句中可以使用所有这三个表中的列。

您可以控制由ON子句的放置评估的虚拟表。

以下示例创建一个虚拟表(A x B)和一个虚拟表(C x D),然后将这两个连接在一起。

SELECT Foo
FROM   A
       INNER JOIN B
               ON A.X = B.X
       INNER JOIN C
                  INNER JOIN D
                          ON C.Y = D.Y /*Only C and D in scope here*/
               ON A.Z = D.Z  /*All tables back in scope*/

查询优化器可以以任何维护语义的方式实际实现连接。由于内部连接是可交换的和关联的,因此上述示例中的表可以自由地重新排列。对于外连接,重新排列它们可能会改变语义。