目录
一. Create
语法:
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...
1.1 单行数据+全列插入
单行指定列插入:
单行全列插入:
into也可以省略:
1.2 多行数据+全列插入
多行全列插入:
多行指定列插入:
1.3 插入否则更新
我们知道,如果发生主键或者唯一键冲突的时候,会报错。但是如果就是想要修改原来的数据呢?可以选择性的进行同步更新操作语法。
语法:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
1.3.1 要插入的值与原数据有冲突则更新
而对于 x rows affected有下面的解释:
- -- 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
- -- 1 row affected: 表中没有冲突数据,数据被插入
- -- 2 row affected: 表中有冲突数据,并且数据已经被更新
通过 MySQL 函数获取受到影响的数据行数:
SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
| 2 |
+-------------+
1.3.2 要插入的值与原数据没有冲突则正常插入
如果要插入的值在原数据中并没有,则相当于正常插入语句。
1.3.3 要插入的值与原数据有冲突但是连续更新了两次
如果我们想更新原数据,但是连着运行了两次命令,则第一次正常修改,第二次并不会改变什么。
1.4 替换
-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
并且可以看到id是变了的。
二. Retrieve
语法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
2.1 select 列
2.1.1 全列查询
//通常情况下不建议使用*进行全列查询
//1.查询的列越多,意味着需要传输的数据量越大
//2.可能会影响索引的使用
2.1.2 指定列查询
指定列的查询不需要按定义表的顺序来。
2.1.3 查询表达式
select后面也可以接表达式。
2.1.4 查询结果重命名
语法:
SELECT column [AS] alias_name [...] FROM table_name;
也可以省略as:
2.1.5 对查询结果去重
使用关键字distinct去重:
2.2 where条件
比较运算符:
运算符 |
说明 |
>,>=, |
大于,大于等于,小于,小于等于 |
= |
等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL 安全,例如 NULL NULL 的结果是 TRUE(1) |
!=,<> |
不等于 |
BETWEEN a0 AND a1 |
范围匹配,[a0, a1],如果 a0 |
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) |
- 例子一:英语不及格的同学及英语成绩 ( < 60 )
- 例子二:语文成绩在 [80, 90] 分的同学及语文成绩
- 例子三:数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
- 例子四:姓孙的同学 及 孙某同学
- 例子五:语文成绩好于英语成绩的同学
- 例子六:总分在 200 分以下的同学
而对于下面这种报错:
涉及到执行顺序的问题:
上面语句是按照ABC的顺序执行,所以在执行B的时候还没有total的定义,所以显示unknown。
并且不能再筛选条件处做重命名:
- 例子七:语文成绩 > 80 并且不姓孙的同学
- 例子八:综合查询:孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
- 例子九:查询NULL
''不等于NULL
2.3 结果排序
语法:
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序。
- 例子一:同学及数学成绩,按数学成绩升序显示
默认是升序的。
- 例子二:同学及 qq 号,按 qq 号排序显示
如果有NULL,则NULL视作比任何值都小,升序出现在最上面,降序出现在最下面。
- 例子三:查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示(先按数学,数学相同按英语,英语再相同按语文)
- 例子四:查询同学及总分,由高到低
order by中可以使用表达式。
order by中可以使用列别名,这是区别于where的地方。
因为:
- 例子五:查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
2.4 筛选分页结果
语法:
-- 起始下标为 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;
- 从0开始,筛选3条结果(不包括0):
- 从1开始,筛选4条结果(不包括1):
- 从2开始,筛选4条结果(这种更规范):
建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死。
那么limit有什么用呢?可以进行简单的分页操作。
例如:按id进行分页,每页3条记录,分别显示第1、2、3页。
第一页:
第二页:
第三页:
那么我们再来看看子语句的顺序:
三. Update
语法:
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
对查询到的结果进行列值更新。意思就是先进行查询,再进行列值更新。
- 例子一:将孙悟空同学的数学成绩变更为 80 分
- 例子二:将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
- 例子三:将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
- 例子四:将所有同学的语文成绩更新为原来的 2 倍
注意:更新全表的语句慎用!!!
四. Delete
4.1 删除数据
语法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
- 例子一:删除孙悟空同学的考试成绩
也可以接order by,例如删除排名最后的一名:
- 例子二:删除整张表数据
注意:删除整表操作要慎用!!!
并且MySQL中,表分为表本身和表中的数据。删除整张表删除的是表中的数据,并不影响表结构,修改表结构用alter。
delete整张表并不会清空自增序列的值。
4.2 截断表
语法:
TRUNCATE [TABLE] table_name
注意:这个操作慎用
- 1. 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
- 2. 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚
- 3. 会重置 AUTO_INCREMENT 项
例子:
五. 插入查询结果
语法:
INSERT INTO table_name [(column [, column ...])] SELECT ...
例子:删除表中的的重复复记录,重复的数据只能有一份
六. 聚合函数
函数 |
说明 |
COUNT([DISTINCT] expr) |
返回查询到的数据的 数量 |
SUM([DISTINCT] expr) |
返回查询到的数据的 总和,不是数字没有意义 |
AVG([DISTINCT] expr) |
返回查询到的数据的 平均值,不是数字没有意义 |
MAX([DISTINCT] expr) |
返回查询到的数据的 最大值,不是数字没有意义 |
MIN([DISTINCT] expr) |
返回查询到的数据的 最小值,不是数字没有意义 |
- 例子一:统计班级共有多少同学
- 例子二:统计班级收集的qq号有多少
- 例子三:统计本次考试的数学成绩分数个数
- 例子四:统计数学成绩总分
- 例子五:统计平均总分
- 例子六:返回英语最高分
- 例子七:返回>70分以上的数学最低分
七. group by子句的使用
在select中使用group by 子句可以对指定列进行分组查询:
select column1, column2, .. from table group by column;
分组的目的是为了进行分组之后,方便进行聚合统计。
例子:
创建库的文件,在文章开头的资源中给出,下载scott_data即可:
下载后,上传到Linux平台,然后登陆数据库。
- 创建新的数据库
create database 数据库名;
- 使用新的数据库
use 数据库名;
将刚才上传到服务器的sql文件导入(我服务器中sql文件路径是root/scott_data.sql)
source /root/scott_data.sql
emp员工表:
dept部门表:
salgrade工资等级表:
- 例子一:显示每个部门的平均工资和最高工资
- 例子二:显示每个部门的每种岗位的平均工资和最低工资
- 例子三:显示平均工资低于2000的部门和它的平均工资
having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where。
但是having与where是有区别的,不建议混用:
不要单纯的认为,只有磁盘上的表结构导入到mysql,真实存在的表,才叫做表。
中间筛选出来的,包括最终结果,在我看来,全部都是逻辑上的表!“MySQL一切皆表”。
未来只要我们处理好单表的CURD,所有的sql场景,我们全部都能用统一的方式进行。
总结:
好了,到这里今天的知识就讲完了,大家有错误一点要在评论指出,我怕我一人搁这瞎bb,没人告诉我错误就寄了。
祝大家越来越好,不用关注我(疯狂暗示)