三、💘
连表查询
笛卡尔积:描述了多个表查询的基本执行逻辑(那么什么叫笛卡尔积呢?)
任何两张表都可以用笛卡尔积,但是两个表假如没有关系,计算出来也没有意义。
笛卡尔积像是两个表的乘积,
我们通过上面两张图来看下图,可以观察到有很多不正确的数据,这时候就需要我们找条件去筛选哪些数据是正确的
⚠️⚠️缺点:笛卡尔积比较低效(多表联合查询就很低效),尤其是数据较多的情况下,所以使用它也需要注意,容易把数据库干停机咯。很多慢的sql都是使用这些联表查询。
笛卡尔积的用途
笛卡尔积的用途:
建立四个表
class(id,name,desc(留作备用的串用来匹配)
id :用于存储班级的唯一标识符,设置为主键,并使用 auto_increment 自增。
name :用于存储班级的名称,设为 varchar 数据类型,最大长度为 20。
desc :用于存储班级的描述,设为 varchar 数据类型,最大长度为 100。
需要注意的是, desc 是 SQL 保留字,表示降序排序的关键字,因此需要将其用反引号 ` 包裹起来,以作为列名使用。)
student(ID,sn(备用),name qq_mail,class_id)
id :用于存储学生的唯一标识符,设置为主键,并使用 auto_increment 自增。
sn :用于存储学生的学号,设为 varchar 数据类型,最大长度为 20。
name :用于存储学生的姓名,设为 varchar 数据类型,最大长度为 20。
qq_mail :用于存储学生的 QQ 邮箱,设为 varchar 数据类型,最大长度为 20。
class_Id :用于存储学生所属的班级的标识符。
需要注意的是, class_Id 列作为外键关联到某个班级表上。如果你要设置外键关系,需要先创建班级表,然后在创建学生表时使用 foreign key 语句来关联到班级表的相应列上。
下面这两个就字面意思不用解释。
coursed(id,name);
score (score ,student_id,class_id);
改一下哈
四张表
假如说要查询漩涡鸣人同学的成绩
首先许仙来自:student
成绩来自:score。需要联合查询,
(1).先用笛卡尔积
(2).过滤不正确的结果,指定连接条件进行筛选。
(3).只关注鸣人,进一步筛选
(4).只关注特定的行和列,进行精简处理
假如查询所有同学的成绩,及个人信息,列出同学的名字,课程名字,分数来组织
同学:student
课程名字:course
分数:score
(1).三个表先笛卡尔积(遇事不决,笛卡尔积)
(2).指定条件
想清楚一件事哈:执行笛卡尔积电脑上其实很快的,但是显示半天才结束,是因为慢在显示,这个是控制台打印的锅。
(3)具体罗列条件,如下图
当然我们针对一些东西,可以起别名
select student name as studentName cour.name as courseName,score.score from student,score,course where···(简写,就是回顾一下,了解这个,怎么起别名就好)
上面的是内连接的方法1
下面是内连接的方法2:大同小异 多了个inner(可以省略,了解就好),join 前面多个表,分割现在用join(相当于逗号)分割,只写join不写on是完整的笛卡尔积,on表示连接条件⚠️⚠️⚠️join是在连接表的时候,前面还是要用逗号,join只是在连接表的时候相当于逗号。
四、💖
外连接
使用的是 (查询任意操作)表 left/right join 表
student(id,name)
score(studentId ,score)
假如此时左侧表中每一条有记录,都可在右侧有对应,则内外连接没有区别,但是一旦两个表对不上,内外连接就会有所不同
正如我上面的许仙之类的,在score中没有他。
内连接的结果一定是两个表中都存在的数据(公共部分):如下图
左外连接,以左侧表为主,右侧表的每个记录,都会存在最终结果里,如果左侧表存在,右侧表不存在的数据,就会把对应的列填成空值
右外连接,以右侧表为主,左侧表的每个记录,都会存在最终结果里,如果右侧表存在,左侧表不存在的数据,就会把对应的列填成空值
全外连接(outer join)-(mysql不支持,但是oracle支持)
我们在平时,尽量不写复杂的SQL,否则把SQL拆出来优化,本身是一件非常复杂的事情,只可以彻底重构。