目录
1.表的增删查改
2.Create操作
insert 语句
插入单行数据
插入多行数据
插入否则更新
替换
3.Retrieve操作
select 子句
全列查询
指定列查询
查询字段为表达式
为查询结果指定别名
去重
where子句
使用示例
order by 子句
使用示例
limit 子句
使用示例
4.Update操作
update 子句
使用示例
5.Delete 操作
delete 子句
使用示例
truncate语句(截断表)
6.插入查询结果
7.聚合函数
使用示例
8.group by 子句
使用示例
where和having的区别
1.表的增删查改
MySQL是关系型数据库,也就是基于表的数据库,也就少不了对表CRUD操作;在MySQL当中,我们应该这么理解CRUD。
- C:create的意思,也就是创建表的内容。
- R:retrieve的意思,也就是读取表的内容。
- U:update的意思,也就是更新表的内容。
- D:delete的意思,也就是删除表中的内容。
2.Create操作
insert 语句
insert就是向表中插入数据,语法如下:
insert [into] table_name [(column_list)] values (value_list);其中:
column_list: 表示列名,可以指定列插入
value_list: 表示对应列的内容,需要和列名对应
使用insert可以进行如下操作:
- 插入单行数据
- 插入多行数据
- 插入否则更新
我们以这张表进行示例演示:
create table if not exists students ( id int unsigned primary key auto_increment, sn int not null unique comment '学号', name varchar(10) not null
);
插入单行数据
在使用insert语句插入数据的时候,在表名左边不指定列名就表明需要进行全列插入,指定列名就表示向指定列插入(当然,如果指定全部的列名也表示全列插入);表名右边就是我们要插入的记录各列的值。
全列插入示例:
insert into students values (1, 2000, '张三');
指定列插入示例:
insert into students (sn, name) values (2001, '李四');
插入多行数据
插入多行数据的时候只需要在values的右边写出多条记录的值,并且用逗号(英文)隔开即可,同时也可以进行全列插入或指定列插入。
全列插入示例:
insert into students values (3, 2002, '王五'),(4, 2003, '赵六');
指定列插入示例:
insert into students (sn, name) values (2004, '田七'),(2005, '赵八');
插入否则更新
在我们插入数据的时候,可能因为主键or唯一键对应的值已经存在而导致插入失败,这是,我们可以使用insert语句的 “插入否则更新” 功能。
也就是说,如果插入的数据不存在冲突,则直接插入;如果插入的数据冲突,就会更新成我们指定的数据。
语法如下:
insert [into] table_name [(column_list)] values (value_list)
on duplicate key
update column1 = value1 [, column2 = value2] ...
- 其中on duplicate key的意思就表示 —— 当出现重复key的时候。
使用示例:
替换
MySQL为了更方便用户使用插入否则更新功能,提供了一个替换语句,语法如下:
replace [into] table_name [(column_list)] values (value_list);
- 其实就是 将insert 语句的insert改为 replace。
它的功能和insert语句的插入否则更新功能是一样的:
- 如果不存在冲突的数据,则直接插入。
- 如果存在冲突的数据,则将冲突的数据更新成现在的值。
3.Retrieve操作
select 子句
select 语句通常用来读取表的内容。
语法如下:
select[distinct] {* | {column [, column] ...}[from table_name][where ...][order by column [asc | desc], ...]limit ...
全列查询
全列查询表名需要查询整张表,语法如下:
select * from 表名;
- 其中的*就表明需要进行全列查询。
示例:
通常情况下不建议使用 * 进行全列查询,因为:
- 查询的列越多,意味着需要传输的数据量越大;
- 可能会影响到索引的使用。
指定列查询
指定列查询只会显示我们指定的列,语法如下:
select column1,column1... from 表名;
示例:
查询字段为表达式
select 语句可以对表达式进行运算。
示例:
为查询结果指定别名
示例:
去重
为指定结果进行去重,需要使用distinct关键字。
where子句
前面我们在使用select子句的时候,都是将一列数据的全部内容显示出来,如果我们想筛选出符合条件的记录,也就是表中的行,我们就需要使用where子句了。
where子句通常和运算符一起使用,MySQL中的运算符可以分为两类,比较运算符和逻辑运算符。
比较运算符:
运算符 | 说明 |
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,操作NULL 时不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,操作NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
!=, <> | 不等于,二者区别不大 |
BETWEEN a0 AND a1 | 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1) |
IN (option, ...) | 如果是 option 中的任意一个,返回 TRUE(1) |
IS NULL | 是 NULL |
IS NOT NULL | 不是 NULL |
LIKE / NOT LIKE 模糊匹配 | % 表示任意多个(包括 0 个)任意字符; _ 表示任意一个字符 |
逻辑运算符:
运算符 | 说明 |
and | 多个条件必须都为 TRUE(1),结果才是 TRUE(1) |
or | 任意一个条件为 TRUE(1), 结果为 TRUE(1) |
not | 条件为 TRUE(1),结果为 FALSE(0) |
使用示例
我们创建这张表:
create table exam_result (id int unsigned primary key auto_increment,name varchar(20) not null comment '同学姓名',chinese float default 0.0 comment '语文成绩',math float default 0.0 comment '数学成绩',english float default 0.0 comment '英语成绩'
);
并插入如下数据:
insert into exam_result (name, chinese, math, english) values
('张三', 67, 98, 56),
('李四', 87, 78, 77),
('王五', 88, 98, 90),
('赵六', 82, 84, 67),
('田七', 55, 85, 45),
('小红', 70, 73, 78),
('小明', 75, 65, 30);
用例1:查询英语不及格的学生以及英语成绩(<60)
用例2:语文成绩在 [80, 90] 分的同学及语文成绩
使用and连接:
使用 between …… and …… 连接:
用例三: 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
使用or连接:
使用in连接:
用例四:语文成绩好于英语成绩的同学
用例五: 总分在 200 分以下的同学
- 注意:where后面不可以使用重新命名的列名。
- 因为,select语句的执行顺序是:from->where->select。
- 也就是先确定那张表,然后确定行,最后确定列。
- where语句中使用 别名的时候,别名还没定义,所以不能使用。
order by 子句
在我们选择查询结果的时候,可以使用order by子句来对选择结果进行排序。
- asc 为升序(从小到大)
- desc 为降序(从大到小)
- 默认为 asc
语法如下:
select ... from table_name [where ...]
order by column [asc|desc], [...];
使用示例
我们使用 在学习where时的那张表来演示。
用例一:学生名字及数学成绩,按数学成绩升序显示。
用例二:查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
用例三:查询同学及总分,由高到低
- 注意:order by 子句中可以使用列别名
- 这是因为,order by 执行的时候,别名已经定义了。
limit 子句
limit子句通常用来对查询结果进行分页筛选。
limit子句有三种使用方式:
方式一:起始下标为 0,从 0 开始,筛选 n 条结果
select ... from table_name [where ...] [order by ...] limit n;方式二:从 s 开始,筛选 n 条结果
select ... from table_name [where ...] [order by ...] limit s, n方式三:从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
select ... from table_name [where ...] [order by ...] limit n offset s;
使用示例
我们还是使用之前那张表。
我们先把它按总分降序排序:
方式一:提取前三行
方式二:提取前三行
方式三:提取前三行
4.Update操作
update 子句
update 操作用来对表中的数据进行更新。
语法:
update table_name set column = expr [, column = expr ...]
[where ...] [order by ...] [limit ...]
还是使用我们之前的表。
使用示例
用例一:将张三同学的数学成绩变更为 80 分
用例二:将李四同学的数学成绩变更为 60 分,语文成绩变更为 70 分
用例三: 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
用例四:将所有同学的语文成绩更新为原来的 2 倍
5.Delete 操作
delete语句用来删除表中的数据。
delete 子句
delete 子句通常用来删除满足条件的记录,语法如下:
delete from table_name [where ...] [order by ...] [limit ...]
使用示例
用例一:删除小明同学的考试成绩
示例二:删除整张表
我们先创建这样一张表:
然后对整表删除:
然后查看创建表语句:
- 我们发现其auto_increment字段并没有被重置。
truncate语句(截断表)
truncate 语句用于截断表,语法如下:
truncate [table] table_name;
注意:这个操作慎用。
- 只能对整表操作,不能像 delete 一样针对部分数据操作。
- 实际上 truncate 不对数据操作,而是直接对表进行操作,所以比 delete 更快,但是truncate在删除数据的时候,并不经过真正的事物,所以无法回滚。
- truncate 会重置 auto_increment 项。
示例:
先创建这样一张表结构:
然后插入数据:
使用truncate 截断表之后,表为空:
插入一条数据之后,查看创建表的语句:
- 发现自增长从2开始,说明truncate会重置 auto_increment 项。
6.插入查询结果
在MySQL中,我们可以使用将select的查询结构插入一张和当前表结构一样的表中。
语法:
insert into table_name [(column [, column ...])] select ...
使用示例:删除表中的重复数据,表中的重复数据只能有一份
我们先创建一张表,并插入重复数据:
然后我们创建一张和当前表结构相同的表,并将去重的数据插入这张表中:
然后通过重命名表实现原子的去重操作,并查看表中的内容:
这样我们就将一张表中的数据以这样的方式全部去重了。
7.聚合函数
MySQL中提供了一些聚合函数:这些聚合函数值在select 后面使用的,用来统计某一列数据。
聚合函数有如下几个:
函数 | 说明 |
count([distinct] expr) | 返回查询到的数据的 数量 |
sum([distinct] expr) | 返回查询到的数据的 总和,不是数字没有意义 |
avg([distinct] expr) | 返回查询到的数据的 平均值,不是数字没有意义 |
max([distinct] expr) | 返回查询到的数据的 最大值,不是数字没有意义 |
min([distinct] expr) | 返回查询到的数据的 最小值,不是数字没有意义 |
使用示例
我们以这张表为例:
用例一:统计班级有多少名学生
用例二:统计数学成绩总分
用例三:统计全班平均分
- 我们可以使用format函数指定小数点后面的位数。
用例四:返回英语最高分
用例五: 返回 > 70 分以上的数学最低分
8.group by 子句
group by 可以对表进行分组,其实就是把一张大表分成很多小表,然后同时对小表进行操作。
语法如下:
select column1, column2, .. from table group by column;
使用示例
我们先创建一个数据库,数据库中有三张表:
三张表中的内容如下:
dept:
emp:
salgrade
用例一:显示每个部门的平均工资和最高工资
用例二:显示每个部门的每种岗位的平均工资和最低工资
用例三:显示平均工资低于2000的部门和它的平均工资
先统计每个部门的平均工资:
然后选择平均工资小于2000的:
- 如果我们使用where子句的话会报错
- 我们需要使用having来判断
having经常和group by搭配使用,作用是对分组进行筛选。
where和having的区别
WHERE
子句
-
作用:
WHERE
用于在查询过程中过滤行,适用于对原始数据进行筛选。 -
使用场景:通常用于
SELECT
、UPDATE
、DELETE
等语句中,过滤满足条件的行。 -
执行时机:
WHERE
在数据分组(GROUP BY
)和聚合函数计算之前执行。 -
适用对象:
WHERE
只能用于过滤行,不能用于过滤聚合函数的结果。
HAVING
子句
-
作用:
HAVING
用于过滤分组后的结果,通常与GROUP BY
一起使用。 -
使用场景:主要用于过滤聚合函数(如
SUM
、AVG
、COUNT
等)的结果。 -
执行时机:
HAVING
在数据分组(GROUP BY
)和聚合函数计算之后执行。 -
适用对象:
HAVING
通常用于过滤分组后的结果或聚合函数的结果。
最后,需要注意的是SQL查询中各个关键字的执行先后顺序如下:
from > on> join > where > group by > with > having > select> distinct > order by > limit