插入
insert [into] 表名 [(列1 [, 列2] ...)] values (值1) [, (值2)...]
[ ]中为可选项,填入表的列 [(列1[,列2]...)] 可以省略表示全插入,也可以 ( ) 中指定某些列部分插入,(值1) [, (值2)...]表示可以添加多行数据,每行数据包含在 ( ) 中,行与行之间用逗号隔开。
我们先创建一张表student。
单行数据 + 全列插入
多行数据 + 指定列插入
插入否则更新
由于 主键 或者 唯一键 对应的值已经存在而导致插入失败。
insert ... on duplicate key update 列1=值1, 列2=值2 ...;
insert
语句如果出现冲突,则执行后面的列1=值1, 列2=值2 ...
进行值替换。
例如,插入的 (101,10003,'八戒') 记录,id与孙悟空的id相同,即出现主键冲突,那么就会执行 on duplicate key update 后面的语句,将该列数据的 sn 改为 10003,name 改为 八戒。
- 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
- 1 row affected: 表中没有冲突数据,数据被插入
- 2 row affected: 表中有冲突数据,并且数据已经被更新
replace [into] 表名 [(列1 [, 列2] ...)] values (值1) [, (值2)...]
- 主键 或者 唯一键 没有冲突,则直接插入
- 主键 或者 唯一键 如果冲突,则删除后再插入
replace 语句结构与 insert 语句结构一致,只是把 insert 改为 replace。
例如,插入的 (100,10000,'观音菩萨') 记录,id与唐僧的id相同,sn与唐僧的sn相同,即出现主键冲突和唯一键冲突,那么就会删除原数据,插入新数据。这里由于出现主键冲突和唯一键冲突的都是同一列,所以只删除一列,如果出现主键冲突和唯一键冲突的在不同列,那么就会删除两列数据
查询
我们先创建一个考试成绩表格并插入数据
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),
('小朵', NULL, NULL, NULL);
select 表达式1, 表达式2 ... from 表名;
此处的表达式含义非常广,它可以是列名,通配符*
,计算式等。
select 表达式1 [as] 别名1, 表达式2 [as] 别名2 ... from 表名;
[ ]中的as表示as可以省略。
例如,我们可以将chinese,math,english加起来就可以得到的总分成绩重新命名为total
distinct 结果去重
我们查看数学成绩时发现有两列98,如果我们只想查看一列98,即对查询结果去重,那么我们可以在所查询的列前面加 distinct 即可。
where 添加查询条件
比较运算符:
运算符 | 说明 |
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,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 | 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符 |
逻辑运算符:
运算符 | 说明 |
and | 多个条件必须都为 true(1),结果才是 true(1) |
or | 任意一个条件为 true(1), 结果为 true(1) |
not | 条件为 true(1),结果为 false(0) |
示例:
select name,english from exam_result where english<60;
2.语文成绩在 [80, 90] 分的同学及语文成绩
select name,chinese from exam_result where chinese between 80 and 90;
select name,math from exam_result where math=58 or math=59
or math=98 or math=99;
select name,math from exam_result where math in(58,59,98,99);
select name from exam_result where name like '%明';
select name,chinese+math+english total from exam_result where
chinese+math+english<200;
虽然前面已经将chinese+math+english
重命名为了total
,但是where
条件不能写为total<200
查询时报错了,找不到total
这个列,这与语句的执行顺序有关。
其执行顺序为:
- 确定要查询的表,执行
from exam_result
- 确定要查询的条件,执行
where total<200
- 确定查询的列,执行
select name,chinese+math+english total
因为where的执行顺序在确定查询的列之前,所以在查询的列上给chinese+math+english
起别名total,
where语句并不知道。
order by 结果排序
select ... from 表名 where ... order by 列1 [asc|desc], 列2 [asc|desc] ... ;
asc
表示升序,desc
表示降序,如果不指定那么默认为asc
升序。
1.同学及数学成绩,按数学成绩升序显示
select name,math from exam_result order by math asc;
SQL中认为NULL
比所有值都小,所以NULL
被放在了第一列。
select name,chinese+math+english total from exam_result order by chinese+math+english desc;
使用order by
时能不能直接用别名total
呢?
我们发现使用order by时可以使用别名total,这是因为order by是在整个表查询 select name, chinese+math+english total结束后执行完毕,得到了所有符合条件的结果之后order by才进行排序。
其执行顺序为:
- 确定要查询的表,执行
from exam_result
- 确定要查询的条件,执行
where...
- 确定查询的列,执行
select name,chinese+math+english total
- 对查询结果进行排序,执行
order by total desc
limit 筛选分页结果
-- 从 0 开始,筛选 n 条结果
select 表达式 from 表名 [where ...] [order by ...] limit n;
-- 从 s 开始,筛选 n 条结果
select 表达式 from 表名 [where ...] [order by ...] limit s, n;
-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
select 表达式 from 表名 [where ...] [order by ...] limit n offset s;
更新
update 表名 set 列1 = 值1, 列2 = 值2 [where ...] [order by ...] [limit ...]
删除
delete
delete from 表名 [where ...] [order by ...] [limit ...];
我们先将整张表的数据都删除掉,并且执行select
时查询不到任何数据,说明确实删除成功了。执行show create table exam_result\G
时,发现auto_increment=9
,说明delete
是不会清空自增长的。
之后我们再次插入数据。
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),
('小朵', NULL, NULL, NULL);
我们执行select * from exam_result 命令时发现 id 就从9开始自增了。
truncate
两者对比
TRUNCATE
:
- 适用于快速清空表中的所有数据,尤其是在数据量较大时,因为它直接释放数据页,执行速度快,但只能删除整张表,不能像 DELETE 一样针对部分数据操作。
- 不支持条件删除,不能用于有外键约束的表,且操作不可回滚。
-
会重置 AUTO_INCREMENT 项
DELETE
:
- 适用于根据特定条件删除数据,支持事务和回滚,适合删除少量数据或需要条件判断的场景。
- 执行速度较慢,因为它是逐行删除并记录日志。
-
不会重置 AUTO_INCREMENT 项
聚合函数
函数 | 说明 |
count([DISTINCT] expr) | 返回查询到的数据的数量 |
sum([DISTINCT] expr)
|
返回查询到的数据的总和,不是数字没有意义
|
avg([DISTINCT] expr) |
返回查询到的数据的平均值,不是数字没有意义
|
max([DISTINCT] expr) |
返回查询到的数据的最大值,不是数字没有意义
|
min([DISTINCT] expr)
|
返回查询到的数据的最小值,不是数字没有意义
|
1.统计班级共有多少同学
分组
select 表达式 from 表名 [where ...] [order by ...] [limit ...] group by 列名;
创建 employees
表
create table employees (
employee_id int auto_increment primary key,
department varchar(50),
salary decimal(10, 2)
);
-- 插入一些示例数据
insert into employees (department, salary) values
('Sales', 45000),
('Sales', 55000),
('Marketing', 50000),
('Marketing', 60000),
('Engineering', 58000),
('Engineering', 62000);
查询每个部门的平均工资
select department,avg(salary) from employees group by department;