我正在学习使用SQL编程,并且刚刚介绍了自联接。我理解这些是如何工作的,但我不了解他们的目的是什么,除了非常具体的用法,加入员工表自己以整齐地展示员工和他们各自的经理。
可以使用下表证明此用法:
EmployeeID | Name | ManagerID
------ | ------------- | ------
1 | Sam | 10
2 | Harry | 4
4 | Manager | NULL
10 | AnotherManager| NULL
以下查询:
select worker.employeeID, worker.name, worker.managerID, manager.name
from employee worker join employee manager
on (worker.managerID = manager.employeeID);
哪会回来:
Sam AnotherManager
Harry Manager
除此之外,还有其他任何情况下自我加入会有用吗?我无法弄清楚需要执行自联接的场景。
答案 0 :(得分:3)
你的榜样很好。只要表包含外键,自联接就很有用。员工有经理,经理是......另一名员工。因此,自我联接在那里是有意义的。
许多层次结构和关系树非常适合这种情况。例如,您可能将父组织划分为区域,组,团队和办公室。其中每个都可以存储为“组织”,父ID为列。
或许您的公司有推荐计划,并且您想记录哪位客户推荐了某人。它们都是“客户”,在同一个表中,但其中一个与另一个有FK链接。
不的层次结构非常适合这种情况,即实体可能具有多个“父”链接的层次结构。例如,假设您有facebook风格的数据记录每个用户和友情链接到其他用户。 可以适合此模型,但是对于用户拥有的每个朋友,您需要一个新的“用户”行,除了“relationshipUserID”之外,每一行都是重复的专栏或你称之为的任何内容。
在多对多关系中,您可能会有一个单独的“关系”表,其中包含“from”和“to”列,也可能是指示关系类型的列。
答案 1 :(得分:2)
我发现自联接在这种情况下最有用:
让所有与Sam一样为同一经理工作的员工。 (这不一定是分层的,这也可以是:让所有与Sam在同一地点工作的员工)
select e2.employeeID, e2.name
from employee e1 join employee e2
on (e1.managerID = e2.managerID)
where e1.name = 'Sam'
在表格中查找重复项也很有用,但效率非常低。
答案 2 :(得分:1)
这里有几个使用自联接的好例子。我经常使用的那个与"时间表"有关。我在教育方面使用时间表,但在其他情况下也是如此。
我使用自联接来确定两个项目是否相互冲突,例如学生可以安排两个课程同时进行,或者一个房间是双重预订。例如:
CREATE TABLE StudentEvents(
StudentId int,
EventId int,
EventDate date,
StartTime time,
EndTime time
)
SELECT
se1.StudentId,
se1.EventDate,
se1.EventId Event1Id,
se1.StartTime as Event1Start,
se1.EndTime as Event1End,
se2.StartTime as Event2Start,
se2.EndTime as Event2End,
FROM
StudentEvents se1
JOIN StudentEvents se2 ON
se1.StudentId = se2.StudentId
AND se1.EventDate = se2.EventDate
AND se1.EventId > se2.EventId
--The above line prevents (a) an event being seen as clashing with itself
--and (b) the same pair of events being returned twice, once as (A,B) and once as (B,A)
WHERE
se1.StartTime < se2.EndTime AND
se1.EndTime > se2.StartTime
类似的逻辑可用于在时间表数据中找到其他东西,例如可以从A到B到C的一对列车。
答案 3 :(得分:0)
只要您想要将同一个表的记录相互比较,自联接就很有用。示例包括:查找重复地址,查找交货地址与发票地址不同的客户,将每日报表中的总计(保存为记录)与前一天的总数进行比较等。