SQL joins

来源:互联网 发布:网络监视软件 编辑:程序博客网 时间:2024/04/30 01:59

     一直对SQL各种连接不是太懂,索性就建俩表自己动手把各种连接重新学习一遍,在实践中自己摸索比光听老师讲要强点,最起码印象要深刻些。

    先上俩表:

    表A:

SQL> create table A (id int, type int);SQL> select * from A;        ID       TYPE---------- ----------         1          1         2          1         3          2 
    表B:

SQL> create table B(id int ,class int);SQL> select * from B;        ID      CLASS---------- ----------         1          1         2          2

①先从内连接(inner join)开始:

SQL> select * from A inner join B on A.id = B.id;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         1          1          1          1         2          1          2          2
内连接其实比较简单,俩表中存在至少一个匹配时,内连接才返回。如果在B表中没有匹配的,就不会返回该行(注:inner join和join是相同的 )
执行过程:以右表(B表)为基准,遍历左表(A表),直到与B表的id列相同的就返回该行,寄过含有重复列,分别为A表的id列和B表的id列。

②左外连接(left join):

SQL> select * from A left join B on A.id = b.id;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         1          1          1          1         2          1          2          2         3          2
左外连接是返回左表的所有行,即使右表没有与左表匹配的行。如果右表有与左表匹配的行,那么右表该行也返回(注:left join 与left outer join是相同的)
执行过程:以左表(A表)为基准,遍历右表(B表)与A表匹配的B.id。若B表存在B.id = A.id,则进行拼接,返回该行,然后继续遍历B表的下一条B.id查看是否还存在B.id = A.id,如果查询完毕,就进入下一条A.id,继续重复上述步骤。如果B.id没有与A.id相匹配的,则显示左表的所有项,右边全显示为NULL。

③右外连接(right join):

SQL> select * from A right join B on A.id = B.id;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         1          1          1          1         2          1          2          2
右外连接其实与左外连接类似,也是返回右表所有行,即使左表没有与右表匹配的行。如果左表有与右表匹配的行,那么左表该行也返回(right join 与right outer join相同)
执行过程:以B表为基准,其他与左外连接类似,不再赘述。

④再来加点料,来点稍微有点难度的:

SQL> select * from A left join B on A.id = B.id where B.id is NULL;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         3          2
这个解释一下为什么会是这个结果:在where字句之前返回的结果还是左表的所有行(如②所示),但这个where字句要求右表的id列必须为空,所以筛选掉了前两行id不为空的。


SQL> select * from A right join B on A.id = B.id where A.id is NULL;未选定行
这个右连接在没有where字句的时候是返回右表的所有行以及左表与之匹配的行(如③所示),但这个where字句要求左表的id列必须为空,所以所有行都被筛选掉了,其筛选的下场就成苦逼的“未选定行”了。

⑥全连接(full join):

SQL> select * from A full join B on A.id = B.id;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         1          1          1          1         2          1          2          2         3          2
全连接是只要其中某个表存在匹配,就会返回行。


SQL> select * from A full join B on A.id = B.id where A.id is NULL or B.id is NULL;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         3          2
这个全连接在没有where条件筛选前结果如⑥,但这个where字句要求A.id为空或者B.id为空,显然A.id都不为空,所以这个条件不会返回任何行,但B.id为空时存在一行符合条件,所以....

上诉7种情况可以用下图概括出来,虽然不是太清楚,下载下来放大了看再对照本文还是可以看出来的。




       最后介绍一下用(+)来实现的左外连接:

SQL> select * from A,B where A.id = B.id(+);        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         1          1          1          1         2          1          2          2         3          2

(+)可以来这样理解:(+)写在哪个表上,就表示哪个表时匹配表,这里(+)写在B表上,就表示以A为基础表,显示A表的所有记录,B表不足的部分用NULL来填充,所以这个就跟左外连接效果一样(注;(+)只能用where连接,不能用on)。

      同理用(+)来实现右外连接:

SQL> select * from A,B where A.id(+) = B.id;        ID       TYPE         ID      CLASS---------- ---------- ---------- ----------         1          1          1          1         2          1          2          2
原理同上,不再赘述。


相关文章:SQL左右连接中的on and和on where的区别


尊重版权,请保留下方二维码以及本文链接:SQL joins
       

欢迎关注行者摩罗微信公众号(xingzhemoluo),共同交流编程经验,扫描下方二维码即可;


3 0
原创粉丝点击