MySQL表的增删改查(进阶)-下篇
目录
🍉🍉🍉新增
🍊🍊🍊查询
🍃🍃🍃聚合查询
聚合函数
GROUP BY子句
HAVING
🍁🍁🍁联合查询
内连接
外连接
自连接
子查询
合并查询
🍉🍉🍉新增
插入查询结果
查询和新增结合起来,把表1的查询结果,插入到表2中.
得到的结果集合,列数/类型/顺序要和insert into后面的表相匹配.
列的名字是不要求相同的发现顺序不匹配的话可以通过指定列方式插入
或
🍊🍊🍊查询
🍃🍃🍃聚合查询
针对行和行之间进行“聚合操作”
聚合函数
进行聚合查询需要搭配聚合函数
常见的统计总数、计算平均值等操作,可以使用聚合函数来实现,常见的聚合函数有:
其实mysql中还提供更复杂的聚合函数,还能算标准差,方差等…
GROUP BY子句
聚合查询中的重要操作group by-分组查询.
使用group by,指定一个列,就会把列的值相同的行,归到一组中
分完组之后,还可以针对每个组,分别进行聚合查询
针对上述分组结果,是可以排序的
HAVING
GROUP BY子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用WHERE语句,而需要用HAVING
🍁🍁🍁联合查询
实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积:
此时的操作,也就可以理解成,多表查询了,就涉及到两个表,是把两个表的数据综合在一起进行了查询.
要想进行一些更有实际意义的查询,此时就需要指定一些额外的条件,
内连接
再来一个例子
初始化测试数据:
create table classes(id int primary key auto_increment,name varchar(20),`desc` varchar(100)); create table student(id int primary key auto_increment,sn varchar(20),name varchar(20),qq_email varchar(20),classes_id int); create table course(id int primary key auto_increment,name varchar(20)); create table score(score decimal(3,1),student_id int,course_id int); insert into classes(name, `desc`) values ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'), ('中文系2019级3班','学习了中国传统文学'), ('自动化2019级5班','学习了机械自动化'); insert into student(sn, name, qq_email, classes_id) values ('09982','黑旋风李逵','xuanfeng@qq.com',1), ('00835','菩提老祖',null,1), ('00391','白素贞',null,1), ('00031','许仙','xuxian@qq.com',1), ('00054','不想毕业',null,1), ('51234','好好说话','say@qq.com',2), ('83223','tellme',null,2), ('09527','老外学中文','foreigner@qq.com',2); insert into course(name) values ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文'); insert into score(score, student_id, course_id) values -- 黑旋风李逵 (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6), -- 菩提老祖 (60, 2, 1),(59.5, 2, 5), -- 白素贞 (33, 3, 1),(68, 3, 3),(99, 3, 5), -- 许仙 (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6), -- 不想毕业 (81, 5, 1),(37, 5, 5), -- 好好说话 (56, 6, 2),(43, 6, 4),(79, 6, 6), -- tellme (80, 7, 2),(92, 7, 6);
(1)查询“许仙”同学的 成绩
(2)查询所有同学的总成绩,及同学的个人信息:
上述代码也可以通过 join on 的方式再来一次
(3)查询所有同学的成绩,及同学的个人信息:
查询每个同学的成绩,列出同学名字、课程名字、课程分数
虽然上述的例子说明,计算笛卡尔积是可以拿任意个表进行的,但是由于笛卡尔积可能会产生出大量的"中间结果”,此时就会对于性能影响很大.甚至严重的,可能会把数据库给搞挂了。因此,多表联合查询,可以用,用的时候,要慎重,需要先对当前这样的多表查询,大慨会涉及到多少数据量进行操作,有一个"预估”。
外连接
🚩外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。
🏳️🌈🏳️🌈🏳️🌈左外连接就是以左表为基准,能够确保左表中的每个记录都出现在最终结果里,如果左表中的记录,在右表中没有对应的记录,此时就会把右表中的相关字段,填成NULL。
🏳️🌈🏳️🌈🏳️🌈右外连接,是以右表为基准,然后确保右表中的每个记录都出现在最终结果里,如果右表中的某个记录在左表里没有对应的相关字段,填成NULL
自连接
自连接是指在同一张表连接自身进行查询,自己和自己进行笛卡尔积。这是一种“特殊的”奇淫技巧。
💿案例 显示所有“计算机原理”成绩比“Java”成绩高的成绩信息(即计算机原理分数比Java高的同学)
sql中进行的条件查询,是针对两个列进行比较的,不能比较两个行,自连接,本质上就能把行关系,转换成列关系=>这是一个经典的数学思维,把未知问题,转成已知问题。
💡如果当前发现,要查询的条件,是针对两行,而不是两列,就可以考虑使用自连接,进行转换。当然自连接的时候,如果表非常大,此时的连接开销,也会非常庞大,容易就把数据库搞死了。
子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。
🚫本来一个需求,需要通过多个sql来完成的,但是现在就偏偏要把多个sql合并成一个子查询。原则上不推荐大家使用的。
🍋单行子查询:返回一行记录的子查询
💿案例 查询与“不想毕业” 同学的同班同学
👁🗨使用子查询前:👁🗨使用子查询后:
很明显这样的代码看起来就更复杂了😴,如果搞4,5个sql的子查询就又是一个"屎山”代码
🍇多行子查询:返回多行记录的子查询
💿案例:查询“语文”或“英文”课程的成绩信息
⚽️[NOT] IN关键字
👁🗨使用子查询前:
👁🗨使用子查询后:
🏀[NOT] EXISTS关键字:更不推荐🚫
exists非常消耗时间,背后会触发大量的硬盘IO操作,并且代码理解起来也比较复杂…
合并查询
🔑在实际应用中,为了合并多个select的执行结果,可以使用集合操作符union,union all。使用UNION和JNION ALL时,前后查询的结果集中,字段需要一致。
🎸union
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。
🎻union all
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。
📢要求合并的双方,类型、个数、顺序匹配,列名不要求