Mysql——CRUD进阶

本文深入探讨了MySQL的表设计,包括数据库约束、设计原则和表的关系。接着,文章详细讲解了如何进行新增与复杂查询,如聚合查询、GROUP BY、HAVING、联合查询、外连查询、自连查询、子查询和合并查询,提供丰富的实例帮助理解。
摘要由CSDN通过智能技术生成

一、表的设计

1. 数据库的约束
  • NOT NULL - 指示某列不能存储 NULL 值。
  • UNIQUE - 唯一约束,保证某列的每行必须有唯一的值。
  • DEFAULT - 规定没有给列赋值时的默认值。
  • NOT NULL - 和 UNIQUE 的结合。确保某列(或两个列多个列的结 合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
  • FOREIGN KEY - 外键约束,保证一个表中的数据匹配另一个表中的值的参照完整性。
    例子:一个学生对应一个班级,一个班级对应多个学生。classes_id为外键,关联班级表的主键id FOREIGN KEY (classes_id) REFERENCES classes(id)
  • PRIMARY KEY -主键约束,对于整数类型的主键,常配搭自增长auto_increment来使用。插入数据对应字段不给值时,使用最大值+1。
  • CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句。
2. 设计原则(数据库三大范式)
  • 第一范式 —— 列不可再分
  • 第二范式 —— 属性完全依赖于主键
  • 第三范式 —— 属性不依赖于其他非主属性,直接依赖于主键
3.表的关系
  • 一对一
    在这里插入图片描述

  • 一对多
    在这里插入图片描述

  • 多对多
    1 - m : n - 1
    在这里插入图片描述
    下图为中间表的建表语句
    在这里插入图片描述

在一对一的关系中,外键设计在两张表任意一张中都可以;
在一对多关系中,主表到从表通常是1对多,从表到主表1对1,外键设计在从表 ;
多对多关系中,需要设计一张中间表,设计两个外键分别关联两张主表的主键

二、新增与复杂查询(难点)

可以使用 insert + select 完成先查询再插入的操作
例:
-- 将学生表中的所有数据复制到用户表 insert into test_user(name, email) select name, qq_mail from student;

1.聚合查询
1) 聚合函数

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有如下,这些函数都是对结果集进行操作,而不是对表进行查询是先查到expr的得到结果集,再对这个返回的结果集进行聚合函数,在得到结果。
在这里插入图片描述
注意点:
① count可以使用count(*),count(0),count(1),count(字段)。
② sum,avg,max,min都是传入字段或表达式使用。
使用如下:

-- 统计班级共有多少同学
SELECT COUNT(*) FROM student;
SELECT COUNT(0) FROM student;

-- 统计数学成绩总分
SELECT SUM(math) FROM exam_result;
-- 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;

-- 统计平均总分
SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;

-- 返回英语最高分
SELECT MAX(english) FROM exam_result;

-- 返回 > 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 70;
2) GROUP BY

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是 “分组依据字段”,其他字段若想出现在 SELECT 中则必须包含在聚合函数中。

例如:查询每个角色的最高工资、最低工资和平均工资

select role,max(salary),min(salary),avg(salary) from emp group by role;
3) HAVING——group by后替换where

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用HAVING

例如:显示平均工资低于1500的角色和它的平均工资

select role,max(salary),min(salary),avg(salary) from emp group by role
having avg(salary)<1500;
2.联合查询——多表操作(重点)

多表查询是对多张表的数据取笛卡尔积
在这里插入图片描述
select * 可以查询所有列,多张表的列都会显示,结果集行数是每张表的行数相乘。

1)内连查询

连接的两张表都有共同的一列,如果一张有,一张没有,那么就不会显示。

select 字段 from1 别名1 [inner] join2 别名2 on 连接条件1 and 连接条件2 where 其他条件1 and 其他条件2; 

例如:
查询所有同学的总成绩,个人信息,学生表对成绩表是一对多的。

-- 成绩表对学生表是多对1关系,查询总成绩是根据成绩表的同学id来进行分组的 
SELECT 
	 stu.sn, 
	 stu.NAME, 
	 stu.qq_mail, 
	 sum( sco.score )
FROM 
 	student stu 
 	JOIN score sco ON stu.id = sco.student_id 
GROUP BY 
 	sco.student_id;
2)外连查询

外连接分为左外连接和右外连接。左表/右表的数据不会依据连接过滤条件过滤而完全显示。 以左连接为例,左外连左表不依赖连接条件,连接后的结果集根据where条件再次过滤。

-- 左外连接,表1完全显示 
select 字段名 from 表名1 left join 表名2 on 连接条件; 
-- 右外连接,表2完全显示 
select 字段 from 表名1 right join 表名2 on 连接条件;

Tips: 外连与内连的区别
与内连不同的点在于结果集的显示上。可以理解为,在于显示上,内连只会显示两个表相同的列(不同的不会显示),外连是强制遵循一张表显示(如果是左连,就会强制显示左连的表的列,右表如果没有也会显示为null)。

例子:查询所有同学的成绩,及同学的个人信息,其中“老外学中文”该同学没有成绩,也需要显示

-- “老外学中文”同学没有考试成绩,也显示出来了
 select * 
 from student stu 
 left join 
 score sco 
 on 
 stu.id=sco.student_id;
 
-- 对应的右外连接为:
 select * 
 from score sco 
 right join 
 student stu 
 on 
 stu.id=sco.student_id;
3)自连查询

用于同一张数据,多行进行操作。具体的,自连接是指在同一张表连接自身进行查询,可以理解为,是多表查询,但是另一张表是自身。

例如:显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

-- 先查询“计算机原理”和“Java”课程的id
select id,name from course where name='Java' or name='计算机原理';
-- 再查询成绩表中,“计算机原理”成绩比“Java”成绩 好的信息
SELECT
s1.*
FROM
score s1,
score s2
WHERE
s1.student_id = s2.student_id
AND s1.score < s2.score
AND s1.course_id = 1
AND s2.course_id = 3;
4)子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。

① 单行子查询: 返回一行记录的子查询
例:

select * 
from student
where classes_id=(
	select classes_id 
	from student 
	where name='不想毕业');

② 多行子查询:返回多行记录的子查询,使用IN (NOT) EXSIST( NOT ) 关键字。

Tips:IN 和 EXSIST的区别
Ⅰ. IN 和 EXSIST的区别在于,IN先查询内层表,然后把外表和内表做hash连接;
Ⅱ. Exists首先执行外层查询对结果做loop循环,再执行内存查询,用外层的找内层的找到返回真循环直到外层。
Ⅲ. 在外表大的时用in效率更快,内表大用exists更快。

例:

-- 使用IN
select * 
from score
where course_id 
IN
 	(select id from course where
	name='语文' or name='英文');

也可以用于多列包含,例:

SELECT
*
FROM
score
WHERE
( score, student_id, course_id ) IN ( SELECT score, student_id,
course_id FROM score GROUP BY score, student_id, course_id HAVING
count( 0 ) > 1 );
5)合并查询

在实际应用中,为了合并多个select的执行结果,可以使用 集合操作符 union,union all 。使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致

union——用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。
union all——用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

例子:

select * from course where id<3
union
select * from course where name='英文';

等同于

select * from course where id<3 or name='英文';	
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值