MySQL基本查询

目录

表的增删查改

增(create)

单行数据,全列插入

​编辑

多行数据,指定列插入

查(retrieve)

全列查询

指定列查询

表达式字段查询

给字段起别名

查询结果去重

where条件

比较运算符

逻辑运算符

查询示例

查询结果排序

筛选分页结果

改(update)

删(delete)

删除数据

截断表

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

聚合函数

查询统计操作

[group by子句](#group by子句)


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

表的增删查改

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

增(create)

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

创建一张学生表。

单行数据,全列插入

多行数据,指定列插入

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

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

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

通过 duplicate key 关键字实现。

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

通过 replace into 关键字实现。

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

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

查(retrieve)

通过select关键字进行查询。

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

全列查询

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

指定列查询

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

表达式字段查询

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

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

给字段起别名

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

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

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

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

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

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

查询结果去重

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

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

以上我们查询出来的数据都是没有进行筛选过的数据,而数据库表中所有的数据,如果我们要对查询出来的数据进行约束,就要使用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)的同学以及英语成绩。

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

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

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

查询姓孙的同学孙某同学

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

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

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

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

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

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

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

null 和 **' '**的区别?

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

查询结果排序

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

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

注意:null比任何值都小,所以排在最上面。
查询同学各门成绩 ,依次按数学降序英语升序语文升序的方式显示。

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

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

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

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

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

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

筛选分页结果

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

通过limit关键字进行实现。

limit n :显示前n行。

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

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

改(update)

通常我们使用update ... set关键字进行数据的修改。
孙悟空 同学的数学成绩变为80分。

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

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

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

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

删(delete)

删除数据

使用 delete from关键字进行数据的删除操作。
删除孙悟空同学的成绩。

删除整张表的数据。

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

插入相应的数据。

删除整张表的数据。

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

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

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

截断表

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

创建要截断的表。

向表中插入数据。

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

向空表中插入一条数据。

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

查看表结构。

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

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

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

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

使用 insert into ... select... 实现。

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

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

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

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

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

聚合函数

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

查询统计操作

统计班级共有多少同学。

统计班级qq号有多少。

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

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

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

统计数学成绩总分。

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

统计英语成绩最高分。

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

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

group by子句

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

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

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

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

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

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

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

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

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

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

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

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

本期内容到此结束^_^

相关推荐
清风~徐~来9 分钟前
【MySQL】库的操作
数据库·mysql·oracle
文牧之3 小时前
PostgreSQL 用户资源管理
运维·数据库·postgresql
Paraverse_徐志斌7 小时前
MySQL 线上大表 DDL 如何避免锁表(pt-online-schema-change)
数据库·mysql·ddl·mysql锁·锁表·pt-osc
哈哈幸运8 小时前
MySQL运维三部曲初级篇:从零开始打造稳定高效的数据库环境
linux·运维·数据库·mysql·性能优化
愚公搬代码8 小时前
【愚公系列】《Python网络爬虫从入门到精通》055-Scrapy_Redis分布式爬虫(安装Redis数据库)
数据库·爬虫·python
pwzs8 小时前
深入浅出 MVCC:MySQL 并发背后的多版本世界
数据库·后端·mysql
大熊猫今天吃什么8 小时前
【一天一坑】空数组,使用 allMatch 默认返回true
前端·数据库
双叶8369 小时前
(51单片机)LCD显示数据存储(DS1302时钟模块教学)(LCD1602教程)(独立按键教程)(延时函数教程)(I2C总线认识)(AT24C02认识)
c语言·数据库·单片机·嵌入式硬件·mongodb·51单片机·nosql
XY.散人9 小时前
初识Redis · C++客户端list和hash
数据库·redis·缓存
码上飞扬9 小时前
深入 MySQL 高级查询:JOIN、子查询与窗口函数的实用指南
数据库·mysql