问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

SQL中的各种JOIN语法总结

创作时间:
作者:
@小白创作中心

SQL中的各种JOIN语法总结

引用
CSDN
1.
https://blog.csdn.net/2203_75907074/article/details/144619383

SQL中的JOIN语句是数据库操作中非常重要的内容,它允许我们根据一定的条件将多个表中的数据进行组合查询。本文将系统地介绍各种JOIN语法,包括INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN等,并通过具体的SQL语句和示例表格帮助读者理解。此外,文章还将对比NATURAL JOIN和USING关键字的使用,并说明ON和WHERE子句的区别。最后,文章还会特别提到MySQL和Oracle在JOIN语法上的细微差别。

SQL JOINS 总结

首先一图总结各种 SQL JOINS:

接下来我们以下面的两个表为例,一个一个讲解

(注:以下内容均在Oracle下进行,文末会提到MySQL和Oracle的区别):

Table A:

Table B:

(INNER) JOIN

内连接,非常的简单啊,就是两个表的交集:

注意这些连接都需要指定 ON 关键字,表示连接条件(关于 ON 和 NATURAL、USING 的区别后面再说)。

对上面俩表使用 INNER JOIN(SQL语句中INNER可以省略):


SELECT *  

FROM A INNER JOIN B  

ON A.course_id = B.course_id;  

输出结果如下,可以看到这里的course_id是原来两个表共有的(并且由于ON关键字的特性,这里的两个course_id并未被合并,这一点我们之后会详细解释):

LEFT (OUTER) JOIN

左外连接,先左后外。也就是先把Table A整个copy来再说,再在Table B中找有没有匹配的部分,没有匹配的部分就用NULL代替:

对上面俩表使用 LEFT JOIN:


SELECT *  

FROM A LEFT JOIN B  

ON A.course_id = B.course_id;  

输出结果如下,可以看到结果中含有Table A的全部内容,并且由于Table B中没有course_id=2的元组,所以在teacher_name属性内为NULL:

RIGHT (OUTER) JOIN

右外连接,先右后外。也就是先把Table B整个copy来再说,再在Table A中找有没有匹配的部分,没有匹配的部分就用NULL代替,整个过程和左外连接一致:

对上面俩表使用 RIGHT JOIN:


SELECT *  

FROM A RIGHT JOIN B  

ON A.course_id = B.course_id;  

输出结果如下,可以看到结果中含有Table B的全部内容,并且由于Table A中没有course_id=4的元组,所以在teacher_name属性内显示NULL:

FULL OUTER JOIN

全外连接,就是将左边和右边嗯塞一起,空的部分就填上NULL,也是非常简单:

对上面俩表使用 FULL OUTER JOIN:


SELECT *  

FROM A FULL OUTER JOIN B  

ON A.course_id = B.course_id;  

输出结果如下,可以看到结果中含有Table A和Table B的全部内容,俩表各自没有的部分都显示为NULL:

其他情况的连接

这张图中还展示了一些其他的连接方式,其实已经没有新东西了,都是上述四种连接的结合,更具体地说,是三种外连接去掉内连接的情况:

可以看到,这三种连接都使用了WHERE子句,保证另一个表中必有NULL值(也就是另一个表中没有的部分)。以LEFT JOIN的情况为例,对上面俩表进行操作:


SELECT *  

FROM A LEFT JOIN B  

ON A.course_id = B.course_id  

WHERE B.course_id IS NULL;  

输出结果如下,意为只在Table A中有,而Table B中没有的元组:

RIGHT JOIN和FULL OUTER JOIN的情况也差不多,兹不赘述(应该……不需要吧?)

NATURAL关键字

除此之外你可能还会见到一种连接方式,就是NATURAL JOIN。

其实NATURAL JOIN并不是一种单独的连接方式,而是NATURAL关键字在起作用,它代表着自动查询两张表中所有相同的字段,然后再进行等值连接。

例如上面的INNER JOIN代码可以重写成如下形式:


SELECT *  

FROM A NATURAL JOIN B;  

因为两表中只有course_id相同,所以这段语句的运行效果就等同于前面的INNER JOIN,但在显示格式上有所区别!

可以看出相较于ON,NATURAL将相同的course_id合并了,在观感上和存储上显然都是更合适的。

但要注意的是,如果两个表之间存在多个相同字段,而我们只想根据某一个相同字段进行查询时,还是得老老实实写ON。

除了NATURAL JOIN之外,也可以有NATURAL LEFT JOIN,NATURAL FULL OUTER JOIN等,总之NATURAL就是ON的简易替换,并且在显示上稍有区别。

例如以下是NATURAL LEFT JOIN的查询结果:

USING关键字

除了NATURAL外,我们还可以使用USING指定需要以其为根据的相同字段。

例如还是INNER JOIN的例子,我们可以重写成如下形式:


SELECT *  

FROM A JOIN B  

USING(course_id);  

也是同样的效果,并且显示结果上和NATURAL JOIN相同,都起到了一个对选定属性集“去重”的作用:

对NATURAL,ON,USING三者可以总结如下:

NATURAL:选中所有相同属性集、去重

USING:选中所有指定的相同属性集、对这些指定属性集去重(对于没有指定的相同属性集则不会去重)

ON:选中所有指定的相同属性集、不去重

CROSS JOIN

使用该连接返回两表的笛卡尔积。

非常普通,普通到了没有存在的必要。

例如下面的两条语句执行起来是一样的。。。


SELECT *  

FROM A CROSS JOIN B;  

SELECT *  

FROM A, B;  

都是两个表的笛卡尔积:

当然我们可以通过加入WHERE子句使其变为等值连接。例如下面的语句和INNER JOIN是等价的:


SELECT *  

FROM A, B  

WHERE A.course_id = B.course_id;  

ON和WHERE

虽然等值条件既可以在ON中写,也可以在WHERE中写,不过因为ON只充当连接条件,而WHERE主要充当选择/过滤条件,因此还是建议将ON和WHERE区分开来。

MySQL中的JOIN

MySQL的JOIN语法与Oracle大致相同,但仍有微小的区别。

首先在Oracle中,INNER JOIN必须跟上ON关键字,否则无法执行;但是在MySQL中INNER JOIN没有ON的话,则表示两个表的笛卡尔积:

其次MySQL不支持FULL OUTER JOIN,可以使用LEFT JOIN UNION RIGHT JOIN的方式替代(Oracle中也可以这么写):


SELECT *  

FROM A LEFT JOIN B  

ON A.course_id = B.course_id  

UNION  

SELECT *  

FROM A RIGHT JOIN B  

ON A.course_id = B.course_id;  

查询结果如下(不得不说MySQL的可视化做得比Oracle好一万倍。。。)

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号