2014-06-19 169 views
1

我一直有麻烦理解这个例子,我有答案,但我有麻烦包装我的头周围如何工作。联接如何工作?SQL加入和左外部加入

检查PLAYER和TEAM表的结构:

PLAYER 
    ------------- 
    PLAYER_ID NUMBER(9) PK 
    LAST_NAME VARCHAR2(25) 
    FIRST_NAME VARCHAR2(25) 
    TEAM_ID NUMBER 
    MANAGER_ID NUMBER(9) 

    TEAM 
    ---------- 
    TEAM_ID NUMBER PK 
    TEAM_NAME VARCHAR2(30) 

在这个例子中,团队经理也播放器,以及MANAGER_ID列引用PLAYER_ID列。对于经理人员,MANAGER_IDNULL

哪个SELECT声明将提供所有球员的列表,包括球员的姓名,球队名称和球员的经理姓名?

答:

SELECT p.last_name, p.first_name, m.last_name, m.first_name, t.team_name 
    FROM player p 
    LEFT OUTER JOIN player m ON (p.manager_id = m.player_id) 
    LEFT OUTER JOIN team t ON (p.team_id = t.team_id); 
+0

要说明这一点,最好的方法是从字面上绘制您的表格的图片。一个在左边,一个在右边。箭头指向哪个方向?这就是你的加入将起作用的方式。您将获得“左侧的所有记录”或“右侧的所有记录”。 – durbnpoisn

回答

2

所以第一LEFT OUTER JOIN则玩家表,然后对每个球员经理信息补充道。每位球员的经理都有一个ID,他也是一名ID的球员。如果A先生,player_id 9是Ted的经理,player_id 5,那么Ted的manager_id将是9。第一次加入需要Ted的manager_id,9,并将其与他的经理A先生的player_id相匹配,以便经理的信息现在也在桌面上,并且m.last_name和​​将显示A先生的姓名。第二次加入需要team_id,并简单地将其与队伍表相匹配,将team_name附加到表中的玩家信息。

如果没有样本数据和图表,很难解释。抱歉。

+1

实际上我有这种感觉。我会再次浏览一遍,我想我会理解这是如何工作的。谢谢! – dood

0

更简单的思考方法是分别查看每个joins

A Left Outer JoinJoin的一种,它在提供的配对上将两个表连接在一起,如果存在匹配,则从右侧拉取数据​​。但是,如果找不到匹配,从右边返回的数据只是Null。这与Inner Join不同,如果找不到匹配,则简单地省略记录。

对于这一点,玩家可能会或可能不会有一个经理,所以它的使用Left Outer Join要么拉回经理Player记录,如果球员有一个经理,或者如果玩家没有,它会返回Null

同样,玩家可能会或可能不会是一个团队,所以它是Left Outer Join荷兰国际集团的Team表拉回Team信息,如果玩家是一个团队,否则这将是Null

Select声明只是简单地从三个表中选择想要显示的字段。

不同类型的Join S的一个很好的例子可以看这里:Difference Between Inner and Outer Joins

3

在你的榜样,同时也是管理者的球员,在的manager_id列空值。就拿SQL语句,它是第一部分:

SELECT p.last_name, p.first_name, m.last_name, m.first_name, t.team_name 
FROM player p 
LEFT OUTER JOIN player m ON (p.manager_id = m.player_id) 

既然你执行的是LEFT JOIN(而不是INNER JOIN),你的经理记录不会被过滤掉(即使在他们的NULL值manager_id列将不会成功加入player表中的任何player_id),并且m.last_name和m.first_name对于这些管理员玩家将为NULL。

如果您要将查询更改为INNER JOIN,那么您的管理员的球员根本不会被查询返回,因为他们对于manager_id具有NULL值,并且没有player_id的球员记录的NULL。

SELECT p.last_name, p.first_name, m.last_name, m.first_name, t.team_name 
FROM player p 
INNER JOIN player m ON (p.manager_id = m.player_id) 

我希望这有助于!

+0

啊我明白了。内部联接只会返回所有没有经理的球员。 LEFT OUTER将返回所有球员和经理。 – dood

+1

你明白了!起初很难想象,我真的在这个概念上挣扎了很长时间。 – MDiesel