我不理解自连接的必要性。有人能给我解释一下吗?
一个简单的例子会非常有帮助。
您可以将自连接视为两个相同的表。但在规范化中,您不能创建表的两个副本,因此您只能使用自连接模拟具有两个表的情况。
假设您有两个表:
emp1
Id Name Boss_id
1 ABC 3
2 DEF 1
3 XYZ 2
emp2
Id Name Boss_id
1 ABC 3
2 DEF 1
3 XYZ 2
现在,如果你想获取每个员工的姓名以及他或她的上级名称:
select c1.Name , c2.Name As Boss
from emp1 c1
inner join emp2 c2 on c1.Boss_id = c2.Id
将输出以下表格:
Name Boss
ABC XYZ
DEF ABC
XYZ DEF
当你有一个表格引用自身时,这是非常常见的情况。例如:员工表中每个员工都可以有一个经理,并且您想列出所有员工及其经理的名称。
SELECT e.name, m.name
FROM employees e LEFT OUTER JOIN employees m
ON e.manager = m.id
自连接是将一个表与其本身进行连接的操作。
常见的使用情况是当表存储实体(记录)之间存在层次关系时。例如,一个包含个人信息(姓名、出生日期、地址等)的表,其中包括一列包含父亲(和/或母亲)ID的信息。然后可以通过简单的查询语句进行操作:
SELECT Child.ID, Child.Name, Child.PhoneNumber, Father.Name, Father.PhoneNumber
FROM myTableOfPersons As Child
LEFT OUTER JOIN myTableOfPersons As Father ON Child.FatherId = Father.ID
WHERE Child.City = 'Chicago' -- Or some other condition or none
我们可以在同一查询中获取关于子代、父亲(和母亲,在第二个自连接等)甚至祖父母等的信息。
假设你有一个表users
,设置如下:
在这种情况下,如果您想要在一个查询中提取用户信息和管理者信息,您可以这样做:
SELECT users.user_id, users.user_name, managers.user_id AS manager_id, managers.user_name AS manager_name INNER JOIN users AS manager ON users.manager_id=manager.user_id
想象一张名为Employee
的表格,如下所述。所有员工都有一个经理,这个经理也是一个员工(也许除了CEO,他的manager_id可能为空)。
Table (Employee):
int id,
varchar name,
int manager_id
select e1.name, e2.name as ManagerName
from Employee e1, Employee e2 where
where e1.manager_id = e2.id
SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2,
A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City
ORDER BY A.City;
如果您的表是自引用的,则它们非常有用。例如,对于一个页面表,每个页面可能都有一个next
和previous
链接。这些将是相同表中其他页面的ID。如果您想获取连续三个页面的三元组,您需要使用相同表的id
列在next
和previous
列上进行两次自连接。
如果表不能引用自身,我们就必须为层次结构中的每个级别创建同样数量的表。但是由于这种功能可用,您可以将表连接到自身,并且sql将其视为两个单独的表,因此所有内容都存储在一个地方。
这里有许多正确的答案,但同样正确的一种变体是:您可以将连接条件放在联接语句中而不是WHERE子句中。
SELECT e1.emp_id AS 'Emp_ID'
, e1.emp_name AS 'Emp_Name'
, e2.emp_id AS 'Manager_ID'
, e2.emp_name AS 'Manager_Name'
FROM Employee e1 RIGHT JOIN Employee e2 ON e1.emp_id = e2.emp_id
记住有时候你想要 e1.manager_id > e2.id。
知道这两种情况的优点是,有时你有很多 WHERE 或 JOIN 条件,想把自己连接条件放在其他子句中,以保持代码的可读性。
没有人提到当员工没有经理时会发生什么。嗯?他们不会被包括在结果集中。如果你想包括没有经理的员工,但又不想返回不正确的组合,该怎么办?
试试这个吧;
SELECT e1.emp_id AS 'Emp_ID'
, e1.emp_name AS 'Emp_Name'
, e2.emp_id AS 'Manager_ID'
, e2.emp_name AS 'Manager_Name'
FROM Employee e1 LEFT JOIN Employee e2
ON e1.emp_id = e2.emp_id
AND e1.emp_name = e2.emp_name
AND e1.every_other_matching_column = e2.every_other_matching_column
自连接在你需要评估表格数据本身时非常有用。这意味着它将关联来自同一表格的行。
语法:SELECT * FROM TABLE t1, TABLE t2 WHERE t1.columnName = t2.columnName
例如,我们想要找到其初始职称等于当前职称的员工姓名。我们可以使用以下方式通过自连接解决此问题。
"最初的回答"
SELECT NAME FROM Employee e1, Employee e2 WHERE e1.intialDesignationId = e2.currentDesignationId