文章目录
- [1. 插入 insert](#1. 插入 insert)
-
- [1.1 单行插入](#1.1 单行插入)
- [2.2 多行插入](#2.2 多行插入)
- [2.3 插入 否则更新](#2.3 插入 否则更新)
- [2.4 替换](#2.4 替换)
- [2. 查找 select](#2. 查找 select)
-
- [2.1 select 列](#2.1 select 列)
- [2.2 where 条件](#2.2 where 条件)
- [2.3 order by 排序](#2.3 order by 排序)
- [2.4 筛选分页结果](#2.4 筛选分页结果)
- [3. 更新 update](#3. 更新 update)
- [4. 删除 delete](#4. 删除 delete)
- [5. 截断 truncate](#5. 截断 truncate)
- [6. 插入查询结果](#6. 插入查询结果)
- [7. 聚合函数](#7. 聚合函数)
- [8. group by子句](#8. group by子句)
我们经常说数据库就是CRUD操作,那CRUD到底是什么呢?
CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)
1. 插入 insert
sql
INSERT [INTO] table_name [(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value[, value,...]
其中:
- into 可以省略
- values 左侧的列名省略,则为全列插入
已有如下表
1.1 单行插入
2.2 多行插入
多行数据之间用逗号隔开
2.3 插入 否则更新
由于 主键 或者 唯一键 对应的值已经存在而导致插入失败
sql
INSERT 插入语句 ON DUPLICATE KEY UPDATE column = value [, column = value] ...
| 重复时,执行后面的操作 | 要更新的列
对于插入或更新后的结果,有以下三种
- 0 row affected : 表中有冲突数据,但冲突数据的值和 update 的值相等
- 1 row affected : 表中没有冲突数据,数据被插入
- 2 row affected : 表中有冲突数据,并且数据已经被更新(先删除旧数据,再插入新数据)
2.4 替换
sql
replace into 表名 [column,...] values(...);
- 主键 或者 唯一键 没有冲突,则直接插入;
- 主键 或者 唯一键 如果冲突,则删除后再插入
2. 查找 select
sql
SELECT [DISTINCT] {* | {column [, column] ...} [FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
- *查询全部
- 指定列名,则查询指定列,多列之间逗号隔开
- select非常特殊,它会执行后面的语句。 例如: select 1 + 1 --> 2
已有如下表:
2.1 select 列
- 全列查询
- 指定列查询
指定列的顺序不需要按定义表的顺序来
- 查询字段为表达式
- 表达式不包含字段
- 表达式包含字段
- 为查询字段指定别名
sql
SELECT column [AS] ,column [AS] [...] FROM table_name;
- 结果去重
为需要去重的列名前添加:distinct
2.2 where 条件
比较运算符
运算符 | 说明 |
---|---|
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
!=, <> | 不等于 |
BETWEEN a AND b | 范围匹配,[a, b] ,如果 a <= value <= b,返回 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);条件为FALSE,结果为TRUE |
下面,我们使用一些小案例来实战一下:
我已有如下表:
- 英语在80分以下的同学及其英语成绩
- 语文成绩在 [80, 90] 分的同学及语文成绩
- 数学成绩是 78 或者 98 或者 99 分的同学及数学成绩
- 姓孙的同学 及 孙某同学
多个 _
一起使用
- 总分在 250 分以下的同学
在where 语句后,我们不能使用重命名后的名字。
这是因为,重命名是对已经筛选完成的数据进行重命名,数据已经要显示了,不能作为筛选条件
要注意SQL的执行顺序。
- 语文成绩 > 80 并且不姓孙的同学
- 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
- NULL 的查询
NULL 和 NULL 的比较,= 和 <=> 的区别
2.3 order by 排序
sql
select ... from 表名 [where] order by 列名 [ASC | DESC]
- ASC(ascending):升序
- DESC(descending):降序
- MySQL默认是升序的,但是不要依赖这个顺序
- 同学及数学成绩,按数学成绩升序显示
其中,NULL 视为比任何值都要小
- 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
- 查询同学及总分,由高到低
这里可以使用order by是因为:order by是对查询的结果进行排序,此时已经查完了,只是数据没有显示出来,排完序后再显示。
- 查询姓孙的同学或者姓熊的同学数学成绩,结果按数学成绩由高到低显示
2.4 筛选分页结果
语法:
sql
-- 起始下标为 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;
建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死
3. 更新 update
对查询到的结果进行列值更新
sql
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
- 将孙悟空同学的数学成绩变更为 80 分'
- 将八戒同学的数学成绩变更为 60 分,语文成绩变更为 70 分,英语成绩变为100分
- 将同学的数学成绩加上 30 分
- 将所有同学的语文成绩更新为原来的 2 倍
4. 删除 delete
语法:
sql
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
删除整表的数据(慎用)
5. 截断 truncate
清空整张表中的内容
- 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
- 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事务,所以无法回滚
- 会重置 AUTO_INCREMENT 项
语法:
sql
TRUNCATE [TABLE] table_name
6. 插入查询结果
题目要求:删除表old_table中的的重复复记录,重复的数据只能有一份
思路:创建两张一样的表,将old_table查询出来的结果,去重后放入new_table,然后两表更换表名。
为什么最后要通过rename的方式?
因为不断地向一个表中插入数据不是原子的;rename是原子的,就是想等一切都就绪了,然后统一放入、更新、生效等
7. 聚合函数
函数 | 说明 |
---|---|
COUNT([DISTINCT] expr) | 返回查询到的数据的 数量 |
SUM([DISTINCT] expr) | 返回查询到的数据的 总和,不是数字没有意义 |
AVG([DISTINCT] expr) | 返回查询到的数据的 平均值,不是数字没有意义 |
MAX([DISTINCT] expr) | 返回查询到的数据的 最大值,不是数字没有意义 |
MIN([DISTINCT] expr) | 返回查询到的数据的 最小值,不是数字没有意义 |
- 统计班级共有多少同学
- 统计本次考试的数学成绩分数个数
- 统计数学成绩总分 与平均分
- 返回 > 70 分以上的数学最低分
8. group by子句
在select中使用group by 子句可以对指定列进行分组查询
语法:
sql
select column1, column2, .. from table group by column;
分组的目的:分组后,方便聚合统计
我们已有如下三张表:
- EMP员工表
- DEPT部门表
- SALGRADE工资等级表
- 如何显示每个部门的平均工资和最高工资
通过order by指定按照哪一列进行分组,就是先使用不同行的该列数据 来进行分组的,分组后组内的列值一定相同的,此时该组中的该列就是可以被聚合压缩
- 显示每个部门的每种岗位的平均工资和最高工资
一般而言,只有在group by后面出现的列才可以被聚合压缩,才可以显示出来;不在group by后面出现的不能显示。
- 显示平均工资低于2000的部门和它的平均工资
首先,要统计各个部门的平均工资;然后having和group by配合使用,对group by结果进行过滤。
having:对分组聚合后的数据,进行条件筛选
看到这里 感觉 having 与where 差不多呀,到底是不是这样呢?
二者条件筛选的时机是不同的
面试题:SQL查询中各个关键字的执行先后顺序:
from > on > join > where > group by > with > having > select > distinct > order by > limit