自我加入和内部联接之间有什么区别
答案 0 :(得分:9)
我认为将SELECT语句中的所有表都视为代表自己的数据集会很有帮助。
在您应用任何条件之前,您可以将每个数据集视为完整(例如,整个表格)。
连接只是开始优化这些数据集以查找您真正想要的信息的几种方法之一。
尽管可以设计具有某些关系的数据库模式(主键< - >外键),但这些关系实际上仅存在于特定查询的上下文中。查询编写者可以将他们想要的任何内容与他们想要的任我稍后会给出一个例子......
INNER JOIN将两个表相互关联。在一个查询中通常有多个JOIN操作将多个表链接在一起。它可以变得如此复杂。举一个简单的例子,考虑以下三个表......
STUDENT
| STUDENTID | LASTNAME | FIRSTNAME |
------------------------------------
1 | Smith | John
2 | Patel | Sanjay
3 | Lee | Kevin
4 | Jackson | Steven
ENROLLMENT
| STUDENTID | CLASSID |
-----------------------
2 | 3
3 | 1
4 | 2
CLASS
| CLASSID | COURSE | PROFESSOR |
--------------------------------
1 | CS 101 | Smith
2 | CS 201 | Ghandi
3 | CS 301 | McDavid
4 | CS 401 | Martinez
STUDENT表和CLASS表旨在通过ENROLLMENT表相互关联。这种表称为连接表。
要编写查询以显示所有学生及其注册的课程,可以使用两个内部联接......
SELECT stud.LASTNAME, stud.FIRSTNAME, class.COURSE, class.PROFESSOR
FROM STUDENT stud
INNER JOIN ENROLLMENT enr
ON stud.STUDENTID = enr.STUDENTID
INNER JOIN CLASS class
ON class.CLASSID = enr.CLASSID;
仔细阅读以上内容,你应该看看发生了什么。您将获得以下数据集......
| LASTNAME | FIRSTNAME | COURSE | PROFESSOR |
---------------------------------------------
Patel | Sanjay | CS 301 | McDavid
Lee | Kevin | CS 101 | Smith
Jackson | Steven | CS 201 | Ghandi
使用JOIN子句,我们将所有三个表的数据集限制为仅相互匹配的数据集。 "匹配"使用 ON 子句定义。请注意,如果您运行此查询,则不会看到CLASS表中的CLASSID 4行或STUDENT表中的STUDENTID 1行,因为匹配中不存在这些ID(在此处案例ENROLLMENT表)。查看" LEFT" /" RIGHT" /" FULL OUTER"加入关于如何使这项工作略有不同的更多阅读。
请注意,根据我对"关系的评论"之前,没有理由为什么您无法直接在LASTNAME和PROFESSOR列上运行与STUDENT表和CLASS表相关的查询。这两列匹配数据类型,看看那个!他们甚至有共同的价值!这可能是一个奇怪的数据集来获得回报。我的观点是它可以完成,你永远不知道将来你需要什么才能获得有趣的数据连接。了解数据库的设计,但没有想到"关系"作为不可忽视的规则。
与此同时......自我加入!
考虑下表...
PERSON
| PERSONID | FAMILYID | NAME |
--------------------------------
1 | 1 | John
2 | 1 | Brynn
3 | 2 | Arpan
4 | 2 | Steve
5 | 2 | Tim
6 | 3 | Becca
如果您觉得如此倾向于建立一个包含您认识的所有人以及哪些人在同一家庭中的数据库,那么这可能是它的样子。
例如,如果你想归还一个人,PERSONID 4,你会写...
SELECT * FROM PERSON WHERE PERSONID = 4;
你会得知他和FAMILYID 2家人在一起。然后在家里找到所有的PERSON,你会写...
SELECT * FROM PERSON WHERE FAMILYID = 2;
完成并完成!当然,SQL可以在一个查询中使用,您猜对了,一个自我加入。
这确实触发了对 SELF JOIN 的需求,因为该表包含一个唯一列(PERSONID)和一个用作"类别"的列。 (FAMILYID)。这个概念称为基数,在这种情况下代表一对多或1:M 关系。每个 PERSON 只有一个,但 FAMILY 中有多 PERSON
所以,如果家庭成员的一个成员已知,我们想要返回的是所有成员 ...
SELECT fam.*
FROM PERSON per
JOIN PERSON fam
ON per.FamilyID = fam.FamilyID
WHERE per.PERSONID = 4;
这是你得到的......
| PERSONID | FAMILYID | NAME |
--------------------------------
3 | 2 | Arpan
4 | 2 | Steve
5 | 2 | Tim
让我们注意几件事。单词 SELF JOIN 不会发生在任何地方。这是因为 SELF JOIN 只是一个概念。上面的查询中的单词 JOIN 可能是 LEFT JOIN ,而且会发生不同的事情。 SELF JOIN 的要点是您使用相同的表两次。
从数据集开始考虑我的肥皂盒。这里我们从PERSON表中开始两次数据集。除非我们这样做,否则数据集的实例都不会影响另一个。
让我们从查询的底部开始。 每数据集仅限于那些PERSONID = 4的行。了解我们知道的表格将只返回一行。该行中的FAMILYID列的值为2.
在ON子句中,我们将 fam 数据集(此时仍然是整个PERSON表)仅限制为FAMILYID值匹配一个或多个<的那些行< / strong> 每数据集的FAMILYID。正如我们所讨论的,我们知道每数据集只有一行,因此有一个FAMILYID值。因此, fam 数据集现在只包含FAMILYID = 2的行。
最后,在查询的顶部,我们选择了 fam 数据集中的所有行。
瞧!两个查询合二为一。
总之, INNER JOIN 是几种JOIN操作之一。我会强烈建议进一步阅读LEFT,RIGHT和FULL OUTER JOIN(统称为 OUTER JOINs )。我个人错过了一次工作机会,因为他对OUTER JOIN的了解很少,并且不会让它再次发生!
SELF JOIN 只是您将表格与自身相关联的任何JOIN操作。您选择将该表连接到自身的方式可以使用 INNER JOIN 或 OUTER JOIN。请注意,使用 SELF JOIN ,以便不要混淆你的SQL引擎你必须使用表别名(fam和per来自上面。弥补你的查询有意义的东西)或者没有办法区分不同的版本同一张桌子。
既然您了解了这种差异,那么您就可以开启您的思想,并认识到一个查询可以同时包含所有不同类型的JOIN。这只是您想要的数据以及如何扭曲和弯曲查询以获取数据的问题。如果您发现自己运行了一个查询并获取该查询的结果并将其用作另一个查询的输入,那么您可以使用 JOIN 来使其成为一个查询。
要使用SQL,请尝试访问W3Schools.com在那里有一个本地存储的数据库,其中有一堆表,这些表旨在以各种方式相互关联,并且它充满了数据!您可以创建,删除,插入,更新和选择所需的所有内容,并随时将数据库恢复为默认值。尝试各种SQL出来试验不同的技巧。我自己也在那里学到了很多东西。
很抱歉,如果这有点罗嗦,但当我开始学习SQL并通过使用一堆其他复杂的概念来解释一个概念时,我个人很难理解JOIN的概念。最好从最底层开始。
我希望它有所帮助。如果你可以把JOIN放在后面的口袋里,你就可以用SQL做神奇了!
快乐的查询!
答案 1 :(得分:2)
自联接将表连接到自身。 employee
表可能会自行连接,以便在同一行显示经理姓名和员工姓名。
内部联接连接任意两个表并返回两个表中存在键的行。自连接可以是内连接(大多数连接是内连接,大多数自连接是内连接)。内连接可以是自连接,但大多数内连接涉及连接两个不同的表(通常是父表和子表)。
答案 2 :(得分:1)
内连接(有时称为简单连接)是两个或多个表的连接,只返回满足连接条件的那些行。
自联接是表与自身的连接。此表在FROM子句中出现两次,后跟表别名,用于限定连接条件中的列名。要执行自联接,Oracle Database会合并并返回满足连接条件的表的行。