目录

MySQL基本查询

MySQL基本查询


在MySQL数据库中,表的操作是最重要的,表的操作分为对表结构的操作和对表数据的操作,前几期我们已经学习了对表结构的操作,本期我们将学习对表数据的操作。

表的增删查改

对表数据的操作无非就四种操作, 增(create)删除(delete)查(retrieve)改(update)

增(create)

使用 insert [into] 关键字进行数据的增加操作,我们一般称为数据的插入操作。

创建一张学生表。 https://i-blog.csdnimg.cn/direct/9f2a55f410844d96b45f8f3273ca2db1.png

单行数据,全列插入

多行数据,指定列插入

https://i-blog.csdnimg.cn/direct/daf7eccde7b34019b6deafa7b1e2c507.png

在前几期我们已经学习了主键和唯一键,对于主键和唯一键而言,这一字段的数据是唯一的不能重复,所以如果我们此时插入了重复的数据,就会报错。

https://i-blog.csdnimg.cn/direct/a643863ae6ee4bf58fa88ad15d00d06f.png

为了防止报错的情况,引入了更新和替换的方案。

1.判断插入的数据与表原有的数据产生主键或者唯一键冲突,如果冲突就更新冲突的数据,如果不冲突就直接插入。

通过 duplicate key 关键字实现。

https://i-blog.csdnimg.cn/direct/7a2244718c9541ceac08735215cde386.png

2.判断插入的数据是否与表原有的数据产生主键和唯一键冲突,如果冲突就删除原有的数据,然后插入新的数据,如果没有冲突,则直接插入。

通过 replace into 关键字实现。

https://i-blog.csdnimg.cn/direct/feaeb37d468443839695b4ff00d7b678.png

两种方法的区别就是 duplicate key 同步时,如果插入的数据和原数据冲突,就更新原数据而并不删除,而 replace into 关键字替换时,如果与原数据冲突,就会先删除原数据,然后再进行插入,所以区别就在于对冲突数据的处理方法上。

通常我们说表中的一个数据就是一个记录,也就是表的一行内容。

查(retrieve)

通过 select 关键字进行查询。

创建成绩表exam_result,并且插入对应的数据。

https://i-blog.csdnimg.cn/direct/4f10e36bba5d414eb776e2d838409961.png

全列查询

查询 exam_result 的所有字段的数据。

https://i-blog.csdnimg.cn/direct/bf8b8595a17849b395d2de1af053f632.png

指定列查询

查询 exam_result name字段,chinese字段的所有数据。

https://i-blog.csdnimg.cn/direct/8839804be94648ab99d6fcbb51bca6e2.png

表达式字段查询

将查询出来的 chinese字段 的值+10。

https://i-blog.csdnimg.cn/direct/03a40b26bcfb49eab793f33a77412161.png

查询 namechinese+math+english 字段,可以获得总成绩。

https://i-blog.csdnimg.cn/direct/4b62186bccd844be98b9c40dfac2e557.png

给字段起别名

查询 namechinese+math+english 字段,给 chinese+math+english 起名为 总分 ,可以获得总成绩。

https://i-blog.csdnimg.cn/direct/14734a62c83f4c65988257ebcb4701c9.png

查询 总分<200 分的学生的成绩。

https://i-blog.csdnimg.cn/direct/2c6da1b3884d40aba60db6fb1f7eaa38.png

此时我们惊奇的发现,mysql提示我们 总分 这个字段无法识别,这是为什么呢?

基于此,我们就要引入了sql语句执行顺序的概念,我们规定在sql语句的执行中, where子句是先于select子句执行的 ,所以就自然不能使用select中重命名之后的字段。

可以理解为是where子句先筛选数据,筛选完数据之后,此时select子句再去进行查询。

所以要实现上述情景,就不能使用重命名之后的字段,必须使用数据库表原有的字段。图示如下。

https://i-blog.csdnimg.cn/direct/0474c2f5c5874b42a2b8ac794e3c6c2c.png

查询结果去重

使用 distinct关键字 可以对查询出来的数据进行去重。

通过exam_result 表发现 math 字段有重复的数据,所以我们对查询出来的 math 字段的数据进行去重。

https://i-blog.csdnimg.cn/direct/301f62cd0260428486b76c601a267bb7.png

以上我们查询出来的数据都是没有进行筛选过的数据,而数据库表中所有的数据,如果我们要对查询出来的数据进行约束,就要使用 where 条件。

where条件

比较运算符
运算符说明
>, >=, <, <=大于,大于等于,小于,小于等于
=等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=>等于,NULL 安全,例如 NULL NULL 的结果是 TRUE(1)
!=, <>不等于
BETWEEN a0 AND a1范围匹配,value属于[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, …)(option,…)括号中的可以理解为是一个集合
IS NULL是 NULL
IS NOT NULL不是 NULL
LIKE模糊匹配% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符
逻辑运算符
运算符说明
AND多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT条件为 TRUE(1),结果为 FALSE(0)
查询示例

查询英文成绩不及格(<60)的同学以及英语成绩。

https://i-blog.csdnimg.cn/direct/9f6aeba3daa64c07bbcc9971757f170a.png

查询语文成绩在[80,90]分的同学及语文成绩。

https://i-blog.csdnimg.cn/direct/dea30a3e74574a0daca57793832abff9.png

查询数学成绩是58或者59或者98或者99分的同学及数学成绩。

有两种方法, 一种是使用or进行连接,一种是使用in条件

https://i-blog.csdnimg.cn/direct/a8915b00ec7d427284a31a091ccf5fc8.png

查询 姓孙的同学孙某同学

通过like进行模糊查询, % 代表任意字符, _ 代表一个字符。

https://i-blog.csdnimg.cn/direct/90ea199adf7f4c98977413f413bacdca.png

查询语文成绩好于英语成绩的同学及他们的英语成绩和语文成绩

https://i-blog.csdnimg.cn/direct/10c31b0027aa47eb9ca493ee14001246.png

查询总分在200分以下的同学。

https://i-blog.csdnimg.cn/direct/fa48a0e1aa9749aaba604acf371a9fea.png

查询 语文成绩 > 80 并且 不姓孙 的同学。

https://i-blog.csdnimg.cn/direct/b33c1d357d754999b3777cf7cc4dc162.png

查询 孙某 同学,否则要求 总成绩>200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80。

https://i-blog.csdnimg.cn/direct/783dce973bcc4d40b8fe25b44eb84d4d.png

查询 qq号为空 的学生,和 qq号不为空 的学生。

https://i-blog.csdnimg.cn/direct/25b5469008704224975eaa6aee723c02.png

我们发现null是不能直接使用 = 进行判断的,必须使用 <=> 进行判断 ,一般情况下,判空的操作我们一般使用 is null 或者 is not null

null’ ‘ 的区别?

https://i-blog.csdnimg.cn/direct/8d2d9d3bb640430b80b2e00eb9453f0d.png

简单的来说 ’  ‘ 代表有数据,数据是一个空串,而 null 代表没有数据。比如说学校的考试,小明去了教室考了零分,和小明缺考是不一样的,考了零分证明考了试,只不过成绩为0,缺考就证明没有考试。

查询结果排序

通常我们使用 order by 子句对于查询出来的数据进行排序, asc 排升序, desc 排降序。

查询同学的 数学成绩 ,并对数学成绩 升序 排序。

https://i-blog.csdnimg.cn/direct/c939b953295e45c78b49b325ebc59ca1.png

查询同学 qq号 ,并对 qq号 进行升序排序。

https://i-blog.csdnimg.cn/direct/bbf63cfd040c440ea9dab7e307122579.png

注意 :null比任何值都小,所以排在最上面。

查询同学 各门成绩 ,依次按 数学降序英语升序语文升序 的方式显示。

https://i-blog.csdnimg.cn/direct/e0aa4a3908b14b2abe4e39bcf4f88a05.png

我们发现此时查询出来的结果只有数学成绩符合查询出的要求,这是因为一张表中的数据,不可能同时满足上述的数学成绩降序,英语成绩升序,语文成绩升序。既然无法同时满足,那就满足第一个查询的要求,即数学成绩降序排序。

查询 同学总分 ,并且 由高到低 显示。

https://i-blog.csdnimg.cn/direct/1085bcf66bba49a3b836ceb91ea034b1.png

此时,我们竟然发现,order by 子句中竟然又可以使用别名了,这是为什么呢?

这是因为,sql语句的执行顺序是不一样的,一般情况下,先是通过where子句筛选出符合条件的数据,然后对筛选出的数据进行select查询,然后对查询出来的数据进行order by排序,最终显示。所以order by子句是后于select子句执行的,所以当然可以使用select子句中设置的字段别名。

也正是因为where 和 order by子句的执行顺序是不一样的所以,这两个子句是可以同时出现的。

查询 姓孙 的同学或者 姓曹 的同学 数学成绩 ,结果按 数学成绩由高到低 显示 。

https://i-blog.csdnimg.cn/direct/e2d513f88ce9487f81c2c4b0f21a313c.png

筛选分页结果

有时候我们可能会有只显示查询的数据的前几行的需求,所以此时就引入了筛选分页结果的概念。

通过limit关键字进行实现。

limit  n :显示前n行。

limit  s ,n :从s开始,显示n行。

limit  n offset s :从s开始,显示n行。

https://i-blog.csdnimg.cn/direct/2ab342446a534e478cdfa259dd81de8e.png

https://i-blog.csdnimg.cn/direct/c65e2cde4cbb4b9fbefab3c23899b0d4.png

改(update)

通常我们使用 update … set 关键字进行数据的修改。

孙悟空 同学的 数学成绩变为80 分。

https://i-blog.csdnimg.cn/direct/76986c126dca4a23976eabe8866ad638.png

曹孟德 同学的 数学成绩 更改为 60 分, 语文成绩 更改为 70 分。

https://i-blog.csdnimg.cn/direct/b401742d692341e48d590b1ca2484248.png

总成绩倒数前三3位同学数学成绩加上30 分。

https://i-blog.csdnimg.cn/direct/56d7be9bd7f94578a635240e38b9d086.png

要注意的是, update子句 的执行顺序一定是在 order by子句 之后才执行的,可以理解为先通过 order by 子句将 chinese+english+math 字段查询了出来 并且进行了排序然后最终保留了倒数前3的3个记录 ,最终由 update子句 进行数据更改。

将所有同学的语文成绩更改为原来的两倍。

https://i-blog.csdnimg.cn/direct/6fbe49d6e94b4de39f8da475edb33694.png

如果没有where子句作为筛选条件,则最终更改的就是表中这一字段的所有数据,一般情况下我们不建议全表数据的更改,应该写上对应的where子句作为筛选的条件。

删(delete)

删除数据

使用 delete from 关键字进行数据的删除操作。

删除 孙悟空 同学的成绩。

https://i-blog.csdnimg.cn/direct/247a7b7c30ba41d3a6fc9111cea5d11e.png

删除整张表的数据。

新创建一个用于删除数据的表。

https://i-blog.csdnimg.cn/direct/1efb0b880eb84f4d82942d85cb48b06b.png

插入相应的数据。

https://i-blog.csdnimg.cn/direct/e0c0ef4b1b634f6db02c6b3262d51d6c.png

删除整张表的数据。

https://i-blog.csdnimg.cn/direct/8fc7d230833542b5919c8cacf663c328.png

往空表中再次插入一条数据。

https://i-blog.csdnimg.cn/direct/d33d8eee9baf4c4cac75a7364f07e6f0.png

我们发现,其实我们删除了整张表的数据之后,再次往空表中插入数据时,此时的主键依然是从4开始的,意味着自增并没有清零。

查看表结构,发现此时的主键id对应的auto_increment 字段显示为5,意味着下一条数据的主键从5开始自增。

https://i-blog.csdnimg.cn/direct/0576d8d6b466410097d6cc5b42b70521.png

截断表

简单来说,截断其实就是删除,通过 truncate 关键字对表进行 截断 的操作,需要注意的是, truncate 只能对整张表的数据进行截断,也就是说只能删除整张表的数据,而不能删除一条数据。

创建要截断的表。

https://i-blog.csdnimg.cn/direct/efac0a2eaf2641959d5fe03bedbff6b8.png

向表中插入数据。

https://i-blog.csdnimg.cn/direct/1ed3ee36c2e04356809a4adecb47af54.png

删除所有数据,截断整张表。

https://i-blog.csdnimg.cn/direct/2ed439d740e344a2aa12c00b7306d84c.png

向空表中插入一条数据。

https://i-blog.csdnimg.cn/direct/fc12cee40c454a91adb0cc7a7f095519.png

我们发现此时插入的数据的自增长的主键值竟然变成了1。

查看表结构。

https://i-blog.csdnimg.cn/direct/44d4bdd8ba364b11af376540507bbc0f.png

我们发现此时的自增长主键的值变成了2,意味着下一条数据的主键在没有设置的条件下会默认为2,也就意味着在使用truncate进行截断表时,自增的主键的自增值也会被清零。

综上, delete from 删除整张表和 truncate 删除整张表的区别就是, delete from 不会清空表的自增主键的自增值,后续插入数据,数据的主键依然会按照上一条数据的主键的值进行自增;而 truncate 删除整张表时会重置表的自增主键的自增值,后续再进行数据插入时,自增主键的值又会从起始值 1 开始自增。

查询的结果作为数据插入其它表

select查询出来的数据,也可以作为源数据插入其它的表。

使用 insert into … select… 实现。

要实现对表数据的去重操作,创建duplicate_table表,并插入数据。

https://i-blog.csdnimg.cn/direct/d004680b46184294921ae1159f23ba04.png

查询duplicate_table的所有数据并对查询的数据进行去重,将去重之后的数据作为源数据插入新表,使用select distinct只是对查询的结果进行了去重,对表本身所存储的数据是没有去重的。

https://i-blog.csdnimg.cn/direct/84d5c8b4768c45969b57f0019f48fc21.png

创建 no_duplicate_table为空表,可以使用 cteate table A like B;的sql语句创建A表,这样创建出来的表是一个与B表结构相同的空表。

https://i-blog.csdnimg.cn/direct/a78193f2f6e0453ab95ec718fb0d6485.png

将在 duplicate_table 中查询的不重复的数据作为源数据插入 no_duplicate_table 之中。

https://i-blog.csdnimg.cn/direct/89f55900d6764eeaae566263e4af4e50.png

通过表的重命名实现表的数据的去重操作。 no_duplicate_table表中是去重的数据,而duplicate_table中数据是没有去重的,所以先将duplicate_table重命名为old_duplicate_table,然后再将no_duplicate_table重命名为duplicate_table,此时就实现了原来的duplicate_table表中数据的去重

https://i-blog.csdnimg.cn/direct/b30801150c564edebc3b2dd5f855d1c3.png

聚合函数

函数说明
COUNT([DISTINCT] expr)返回查询到的数据的 数量
SUM([DISTINCT] expr)返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr)返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr)返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr)返回查询到的数据的 最小值,不是数字没有意义

查询统计操作

统计班级共有多少同学。

https://i-blog.csdnimg.cn/direct/71b131804a644dc78a8d124fa7bd5dfe.png

统计班级qq号有多少。

https://i-blog.csdnimg.cn/direct/a7aa6a69089942d38441b0b991e1e8f1.png

需要注意的是, null 本身不计入个数的多少。

统计本次考试的数学成绩分数个数

https://i-blog.csdnimg.cn/direct/09425c120ebb4414b35ea184c8148e1e.png

统计本次考试中不同的数学成绩的个数,简单来说就是对数学成绩去重之后数学成绩的个数。

https://i-blog.csdnimg.cn/direct/7784e63b478f484d9932497e1201a839.png

统计数学成绩总分。

https://i-blog.csdnimg.cn/direct/a7b03e6a2a1f42ab989ac4e083c5d452.png

统计三门成绩的平均总分。

https://i-blog.csdnimg.cn/direct/07c36043abe445d7acfe12f17b656af9.png

统计英语成绩最高分。

https://i-blog.csdnimg.cn/direct/d0d68023cc0f4deea9e4db1642c4cc58.png

统计数学成绩>70分的最低数学成绩。

https://i-blog.csdnimg.cn/direct/b713770d3a7240059f474e3961e4adaf.png

上述情景,得先通过where子句筛选出>70分的数学成绩,然后再通过select子句查询 筛选出来的>70分的所有数学成绩中最低的数学成绩。

group by子句

导入三个表,emp员工表,dept部门表,salgrade工资等级表。

https://i-blog.csdnimg.cn/direct/19b2d8a14aa849b19f603d207b0ad522.png

显示每个部门的最高工资和平均工资。

做一个简单的分析,我们发现部门的编号和部门工资,这两个字段在emp表内,所以我们要先对emp表中的员工记录按照部门编号进行分组,一组代表一个部门,然后再对每组数据进行查询,就可以得到查询结果。

https://i-blog.csdnimg.cn/direct/e1f5cb2394264160a5e69cdbbd7803d5.png

显示每个部门每种岗位的平均工资和最低工资。

做一个简单的分析,部门编号和岗位名称都在emp表里,所以首先对emp表进行查询,然后按照部门编号和岗位名称进行分组,一组就是一个部门的一个岗位所有员工的信息,然后依次对每组进行查询,就可以得到查询结果。

https://i-blog.csdnimg.cn/direct/8356f18145f34ea19d23b999a8f3dca4.png

显示平均工资低于2000的部门和它的平均工资。

https://i-blog.csdnimg.cn/direct/99dd4964b72d471b939bdc7e1fc9d1b2.png

上述查询我们先使用group by对deptno进行了分组,每组就是一个部门的所有员工信息,然后select查询出了分组之后 每个部门的部门编号和平均工资,最终使用 having子句对查询出的每组 的结果进行筛选最终显示了最终的查询结果。

需要注意的是我们发现having子句中是可以用select中起的别名的,所以就可以得知 having子句一定是后于select子句 执行。

因为having子句后于select执行,而where子句先于select子句执行,所以就意味着where和having是可以同时存在的。

显示部门编号 >10 且平均工资大于 1000 的所有部门的部门编号和部门平均工资。

https://i-blog.csdnimg.cn/direct/7906459b113f48f3bd8e22b169cdb969.png

简单来说,where 和 having 都可以作为限制条件,不过where子句先于select执行,而having子句在select之后执行。

以上便是本期的基本查询相关的所有内容。

本期内容到此结束^_^