SQL连接查询及区别

1 篇文章 0 订阅

环境

mysql:mysql-5.7.17-winx64
navicat for mysql:11.1.13

前言

本人玩nosql,玩了三年,结果呢,SQL忘的差不多了,所以今天特意把一些基本概念和用法捡回来;
这三年来,玩nosql(主要针对mongodbes库),可以说玩的贼溜;
还好自己是科班出身,大学本来就学过,把SQL捡回来也是很快,哈哈;
话不多说,先上图:
在这里插入图片描述

为了方便讲解,我们先假设有如下表

学生表(students

在这里插入图片描述
这里我们再复制一张学生表(students_copy
在这里插入图片描述

成绩表(scores

id:主键;自增
sid:就是学生id
cid:就是教师id
score:分数
在这里插入图片描述

教师表(teachers

在这里插入图片描述

连接查询

根据表的不同,如果是自己和自己进行关联查询,称为自连接
如果是不同表之间进行关联查询,就分为内连接外连接交叉连接

自连接

即:表自己和自己关联

-- 自连接
SELECT * FROM students s,students s2 WHERE s.id = s2.id;

效果:
在这里插入图片描述

内连接

内连接其实就是取交集;所以数据会有丢失;

自然连接

语法:

select ... from A natural join B [where]

百度百科的说法:

自然连接(Natural join)是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且在结果中把重复的属性列去掉。而等值连接并不去掉重复的属性列。

但是具体该怎么理解呢?直接看图(用美图秀秀的拼图功能):
在这里插入图片描述

上图 左边是students表,右边是students_copy表;

执行:

-- 自然连接
SELECT * FROM students s NATURAL JOIN students_copy ssc

效果:
在这里插入图片描述
上面是两个表字段都一模一样的效果图;
要是表字段不一样呢(大部分)?比如和教师表关联

-- 自然连接
SELECT * FROM students s NATURAL JOIN teachers t

在这里插入图片描述
总结:

①自然连接,应该是依次比较字段名相同的值是否也相同;如果至少有一个相同,则关联成功,并把关联表中多余的字段也添加进结果;
拿上例来说,tname字段,在students表中没有的,来自关联表(teachers),最后也添加进了结果集中。
② 可以使用where进行筛选;

等值连接

在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列

语法:

SELECT ... FROM A INNER JOIN B [WHERE/ON s.id = sc.sid];

执行:

-- 等值连接
SELECT * FROM students s INNER JOIN scores sc WHERE s.id = sc.sid;
-- 等效于
SELECT * FROM students s , scores sc WHERE s.id = sc.sid;
SELECT * FROM students s , scores sc ON s.id = sc.sid;

在这里插入图片描述

不等值连接

定义:

在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

执行:

-- 不等连接
SELECT * from students s INNER JOIN scores sc WHERE s.id <> sc.sid
-- 等效于
SELECT * from students s, scores sc WHERE s.id <> sc.sid;
-- 不能讲where换成on,会报错
SELECT * from students s, scores sc on s.id <> sc.sid;
-- 但是在指明为内连接的情况下,可以
SELECT * from students s INNER JOIN scores sc on s.id <> sc.sid;

结果:
在这里插入图片描述

外连接

假设有集合A、B两个集合

与内连接不同的是,外连接的基础表数据是完整的。
用集合来说的话,就是集合的范围为 A与B交集 + A(假设A为基础表)

左外连接

即:以左边的表为基础表,进行关联,没关联上的字段,显示为null

语法格式:

select ... from A left join B on A.id = B.id

注意:

上面的on是不能省略的

执行:

-- 左外连接
select ... from students s LEFT JOIN students_copy ssc on s.id = ssc.id;

在这里插入图片描述
总结:

从上图可以看出,基础表的6条数据都显示出来了,关联表里关联上的就显示为null;

右外连接

即:以右边的表为基础表,字段都保留,没关联上的字段就显示null

语法格式:

select  ... from A right join B on A.id = B.id

注意:

上面的on是不能省略的

说明:

右外连接其实和左外连接是一回事,在左外连接的写法上,把A、B两个表交换位置,就变成了右外连接

执行:

-- 右外连接
SELECT * FROM students s RIGHT JOIN students_copy ssc on s.id = ssc.id;

效果:
在这里插入图片描述
总结:

基础表(右边的数据)是完整的,左边没有关联上的,就显示为null;

全连接

没关联的数据字段就显示为null,基本表和关联表的数据都保留。

语法:

select ... from A FULL JOIN B on A.id = B.id;

注意:

上面的on是不能省略的;

说明: 目前mysql是不支持全连接的,Oracle数据库i9以上是支持的。
执行:

-- 全连接
SELECT * FROM students s FULL JOIN students_copy ssc on s.id = ssc.id;

效果,报错:

[SQL]-- 全连接
SELECT * FROM students s FULL JOIN students_copy ssc on s.id = ssc.id;
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FULL JOIN students_copy ssc on s.id = ssc.id' at line 2

交叉连接

就是做笛卡尔积

语法:

select ... from A cross join B
-- 交叉连接
SELECT * FROM students s CROSS join students_copy ssc;
-- 等效于
SELECT * FROM students s, students_copy ssc;
-- 结果是一样的
SELECT * FROM students s INNER join students_copy ssc;

效果:
在这里插入图片描述
注意

这里你会发现,交叉连接查询的结果和INNER JOIN 没有指定on或者where时,结果是一样的,都是笛卡尔积。
可以使用where或者on进行筛选查询。

ON 注意事项

① 不能在自然连接(natural join)中使用。
②不等值连接中,不能写成如下形式:

SELECT * from students s, scores sc on s.id <> sc.sid;

但是可以写成如下形式:

SELECT * from students s INNER JOIN scores sc on s.id <> sc.sid;

为什么会有这种区别呢?
这是因为关键字ONselectfromwhere其实不是一个级别的;
selectfromwhere这些关键字属于顶级关键字,是可以单独使用的;
但是关键字ON,必须和inner joinleft joincross join配合来用的。

所以出现如下形式,也是错误的:

SELECT * FROM scores sc, students s on s.id = sc.sid;

会报如下错误:

[SQL]SELECT * FROM scores sc, students s on s.id = sc.sid;
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on s.id = sc.sid' at line 1

join和union区别

  1. join联结的两个表,是通过匹配两个表中相同字段的相同的值,得到的结果集。可以认为是结果集的列拓宽了。join是使得查询的内容更详细了。
  2. union是取将两个结果集的并集,但两个结果集所拥有的列数是一样、列的顺序也一样、字段类型相同或相似(DBMS认为的相似),才能union并展示在一起。可以认为是结果集的行数多了。union是使得查询的结果更多了。

union会对查到的结果进行去重处理。
union all会将查到的结果直接全部展示出来。

总结

基本把SQL语法捡回来了,并且把关键字ON,算是弄明白了。

参考地址:
https://www.cnblogs.com/caozengling/p/5318696.html
http://www.cnblogs.com/zxlovenet/p/4005256.html
https://blog.csdn.net/jiuqiyuliang/article/details/10474221
https://zhuanlan.zhihu.com/p/46037197
https://blog.csdn.net/u010895119/article/details/80335983
https://blog.51cto.com/12902932/1928058

数据表中数据的来源:
https://www.cnblogs.com/qixuejia/p/3637735.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山鬼谣me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值