了解自我加入

时间:2014-03-08 19:41:25

标签: mysql sql self-join

我正在练习自我加入,这是我在撰写查询时不理解的事情。

我有一张表'employee'

员工表包含三个记录。

+-----+---------------+------------+
| id  | employee      | manager_id |
+-----+---------------+------------+
| 1   | Ola           |   NULL     |
| 2   | Ahmed         |    1       |
| 3   | Tove          |    1       |
+----------+----------+------------+

最后一列manager_id指的是制作Ahmed和Tove的Ola经理的第一列id。

如果我像

那样编写查询
SELECT emp.employee as NAME, manager.employee as MANAGER
FROM employee as emp, employee as manager
WHERE emp.id = manager.manager_id

结果让艾哈迈德和托夫经理。 而

SELECT emp.employee as NAME, manager.employee as MANAGER
FROM employee as emp, employee as manager
WHERE manager.id = emp.manager_id

使其正确,有人可以解释一下吗?

4 个答案:

答案 0 :(得分:2)

自联接就像一个内部联接,其中同一个表的两个或多个实例通过公共数据类型列/字段连接在一起。这种连接(内连接)根据连接条件给出公共行。

员工表包含三条记录。在这种情况下,

员工为emp:

+-----+---------------+------------+
| id  | employee      | manager_id |
+-----+---------------+------------+
| 1   | Ola           |   NULL     |
| 2   | Ahmed         |    1       |
| 3   | Tove          |    1       |
+----------+----------+------------+

员工担任经理:

+-----+---------------+------------+
| id  | employee      | manager_id |
+-----+---------------+------------+
| 1   | Ola           |   NULL     |
| 2   | Ahmed         |    1       |
| 3   | Tove          |    1       |
+----------+----------+------------+

现在第一个案例:让我们试试这个来理解差异:

SELECT emp.*manager.* 员工为emp,员工为经理 WHERE emp.id = manager.manager_id

+-----+---------------+------------+-----+---------------+------------+
| id  | employee      | manager_id | id  | employee      | manager_id |
+-----+---------------+------------+-----+---------------+------------+
| 1   | Ola           |   NULL     | 2   | Ahmed         |    1       |
| 1   | Ola           |   NULL     | 3   | Tove          |    1       |
+----------+----------+------------+----------+----------+------------+

参见,emp.id = manager.manager_id。因此,作为NAME的emp.employee从第一个表&给出了Ola行。作为经理的manager.employee给了Ahmed&从第二张桌子开始。

现在第二个案例:让我们尝试这个来理解差异:

SELECT emp.*manager.* 员工为emp,员工为经理 WHERE manager.id = emp.manager_id

+-----+---------------+------------+-----+---------------+------------+
| id  | employee      | manager_id | id  | employee      | manager_id |
+-----+---------------+------------+-----+---------------+------------+
| 2   | Ahmed         |    1       | 1   | Ola           |   NULL     |  
| 3   | Tove          |    1       | 1   | Ola           |   NULL     |
+----------+----------+------------+----------+----------+------------+

请参阅manager.id = emp.manager_id。因此,作为NAME的emp.employee给出了Ahmed&的行。第一桌和第二桌manager.employee作为MANAGER从第二个表中提供Ola行。

答案 1 :(得分:1)

编写WHERE emp.id = manager.manager_id没有多大意义,因为经理(或想要显示为经理的行)没有manager_id。即,您必须从emp.manager_id开始,因为您要列出员工以及要列出相应经理的该员工的每个manager_id。

答案 2 :(得分:1)

仅当您加入manager.employee时,

manager.id才能为您提供正确的名称 这只发生在第二个查询中。

在ON条件下使用id的表的别名必须相同 它使用employee列,因此manager.id - > manager.employee

答案 3 :(得分:1)

对于每一行,manager_id指的是员工的经理。这是由您的第二个查询描述的。在这里,您将emp.manager_id与联接表中的员工进行匹配。断言由于id列而存在关系 - 换句话说,Ola的经理是manager_id为1的任何人。在这种情况下,Ahmed和Tove的manager_id都是1,所以它们都匹配。 HTH。