MySQL笔记:
https://blog.csdn.net/2301_80220607/category_12971838.html?spm=1001.2014.3001.5482
前言:
前面我们已经学习了表的基本操作类型比如创建删除等和表的约束问题,今天我们来讲解一下我们通过表可以实现的对数据的各项处理功能:增删查改。
关于数据库的增删查改更准确点来讲应该叫CRUD:Create(创建)、Retrieve(读取)、Update(更新)、Delete(删除)
目录
1. Create
这里Create创建实际上就是新增的意思,对数据库新增数据的语法为:
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...
下面我们来讲一下关于INSETRT新增数据的几种不同的用法
首先我们先创建这样一张表(下面几个案例都是往这张表中插入数据):
-----创建一张学生表------
create table student(
-> id int unsigned primary key auto_increment,
-> sn int not null unique,
-> name varchar(20) not null,
-> qq varchar(20)
-> );
1.1 单行输入+全列插入
- 插入两条记录,value_list 数量必须和定义表的列的数量及顺序一致
-- 注意,这里在插入的时候,也可以不用指定id(当然,那时候就需要明确插入数据到那些列了),那么mysql会使用默认
的值进行自增。
INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
Query OK, 1 row affected (0.02 sec)
INSERT INTO students VALUES (101, 10001, '孙悟空', '11111');
Query OK, 1 row affected (0.02 sec)
-- 查看插入结果
SELECT * FROM students;
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10000 | 唐三藏 | NULL |
| 101 | 10001 | 孙悟空 | 11111 |
+-----+-------+-----------+-------+
2 rows in set (0.00 sec)
1.2 多行输入+指定列插入
- 插入两条记录,value_list 数量必须和指定列数量及顺序一致
INSERT INTO students (id, sn, name) VALUES
(102, 20001, '曹孟德'),
(103, 20002, '孙仲谋');
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
-- 查看插入结果
SELECT * FROM students;
+-----+-------+-----------+-------+
| id | sn | name | qq |
+-----+-------+-----------+-------+
| 100 | 10000 | 唐三藏 | NULL |
| 101 | 10001 | 孙悟空 | 11111 |
| 102 | 20001 | 曹孟德 | NULL |
| 103 | 20002 | 孙仲谋 | NULL |
+-----+-------+-----------+-------+
4 rows in set (0.00 sec)
1.3 插入或者更新
我们上面创建的学生表中,id字段是关键字,sn字段则有唯一性约束,这两个字段都不能有重复情况出现,但是如果有时候我们需要对表单中的数据进行更新,比如当前我们表单中的数据为:
我们现在插入这样一组数据:
insert into students values(103,20002,'孙仲谋',22222);
我们会发现插入会失败,失败的原因是主键冲突了,已经存在一个主键值为103的数据,但仔细观察我们插入的这个数据,我们会发现我们仅仅是在原数据的基础上补上了qq号,所以我们希望能有一个方法可以做到这样的效果:
如果数据库中没有这个数据,则直接插入;如果已经存在了这个主键,则对这组数据进行更新
相应的语法为:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
再次插入上面那组数据:
我们可以通过这个函数获取到受影响的行数:
SELECT ROW_COUNT();
1.4 替换
- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
2. Retrieve
语法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
还以我们上面创建的表为例
2.1 全列查询
SELECT * FROM 表名;
2.2 指定列查询
我们可以指定我们要查询的列,比如我们的示例的表中的字段有:id、sn、name、qq,我们可以指定要查看的列,而且可以不用按照原有顺序
2.3 查询结果为表达式
表达式中不含字段
表达式也可以是sql中的一些函数
表达式中含字段
2.4 为查询结果指定别名
语法:
SELECT column [AS] alias_name [...] FROM table_name;
2.5 结果去重
假设如图所示,表中有多个数据都是名为曹操的,我们仅想获得一个,便需要进行去重
SELECT DISTINCT 列名 FROM 表名;
2.6 WHERE条件
逻辑运算符:
运算符 | 说明 |
---|---|
AND | 多个条件必须都为TRUE(1),结果才为TRUE(1) |
OR | 任意一个条件为TRUE(1),结果为TRUE(1) |
NOT | 条件为TRUE(1),结果为FALSE(0) |
案例:
查找name='曹操'的所有数据:
查找qq=’11111'的所有数据:
查找id号在100~110之间的数据:
2.7 对结果进行排序
语法:
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
ASC|DESC:分别表示按升序和降序来排序的意思
案例:
- 按学号降序来排所有学生:
- 按学号升序来排所有数据:
排升序时ASC可以省略不写,因为排序时默认就是按升序来进行排列的
- 有时候还会出现多个判定情况的条件,比如排名次时先按照数学排,如果数学成绩一样就按英语排,再一样就按语文排
-- 多字段排序,排序优先级随书写顺序
SELECT name, math, english, chinese FROM exam_result
ORDER BY math DESC, english, chinese;
+-----------+--------+--------+-------+
| name | math | english | chinese |
+-----------+--------+--------+-------+
比特科技
| 唐三藏 | 98 | 56 | 67 |
| 猪悟能 | 98 | 90 | 88 |
| 刘玄德 | 85 | 45 | 55 |
| 曹孟德 | 84 | 67 | 82 |
| 孙悟空 | 78 | 77 | 87 |
| 孙权 | 73 | 78 | 70 |
| 宋公明 | 65 | 30 | 75 |
+-----------+--------+--------+-------+
7 rows in set (0.00 sec)
2.8 筛选分页结果
语法:
-- 起始下标为 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,避免因为表中数据过大,查询全表数据导致数据库卡死
- limit 3:
- limit 0, 3:
- limit 3 offset 0:
3. Update
语法:
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
对查询到的结果进行列值更新
案例:
将唐三藏的qq号改为12345
先查看一下原表中的数据:
进行更改:
update students set qq='12345' where name='唐三藏';
更改后的数据:
也可以同时对多列内容进行更新!!!
补充:
我们可以更新一个数据中的一个列,也可以同时更新多个列,同时也可以同时对多组数据乃至整个数据库进行更新
4. Delete
4.1 删除数据
语法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
案例:
删除名为曹操的相关数据
-- 查看原数据
select * from students where name='曹操';
+-----+-------+--------+------+
| id | sn | name | qq |
+-----+-------+--------+------+
| 103 | 20002 | 曹操 | NULL |
| 104 | 20003 | 曹操 | NULL |
| 105 | 20004 | 曹操 | NULL |
+-----+-------+--------+------+
3 rows in set (0.00 sec)
-- 删除数据
delete from students where name='曹操';
Query OK, 3 rows affected (0.00 sec)
--查看删除后的数据
select * from students where name='曹操';
Empty set (0.00 sec)
删除整张表的数据:
DELETE FROM 表名;
删除整张表的操作需要十分谨慎,建议先进行备份再进行删除操作,如何备份在前面几篇讲过
4.2 截断表
语法:
TRUNCATE [TABLE] table_name
注意:这个操作更需要慎重!!
- 只能对整表进行操作,不像DELETE那样可以对部份表进行操作
- 实际上MySQL不对数据操作,所以比DELETE更快,但是TRUNCATE在删除数据的时候,并不经过事务,所以无法回滚
- 会重置AUTO_INCREMENT选项(补充:在DELETE删除表项的时候,如果一个字段被设为自增字段,即使它前面的选项已经全部被删除,但是它仍然不会从头开始,而是继续在原基础上增加;但是截断则不同,它把原数据删除了之后,自增字段也会从头开始进行增加)
5. 插入查询结果
语法:
INSERT INTO table_name [(column [, column ...])] SELECT ...
案例:
题目:删除表中的重复数据,重复数据只留下一份
---创建原数据表
CREATE TABLE duplicate_table (id int, name varchar(20));
---插入数据
INSERT INTO duplicate_table VALUES
(100, 'aaa'),
(100, 'aaa'),
(200, 'bbb'),
(200, 'bbb'),
(200, 'bbb'),
(300, 'ccc');
思路:
---创建一个空表 no_duplicate_table,结构和上面那个表一样
CREATE TABLE no_duplicate_table LIKE duplicate_table;
INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
此时我们就可以发现我们新创建的这个数据库就是我们要得到的数据库,然后我们将这个数据库的名字改为原数据库的名duplicate_table,原数据库改成其他名或者删除即可
6. 聚合函数
函数 | 说明 |
---|---|
COUNT([DISTINCT] expr)
|
返回查询到的数据的 数量
|
SUM([DISTINCT] expr)
|
返回查询到的数据的 总和,不是数字没有意义
|
AVG([DISTINCT] expr)
|
返回查询到的数据的 平均值,不是数字没有意义
|
MAX([DISTINCT] expr)
|
返回查询到的数据的 最大值,不是数字没有意义
|
MIN([DISTINCT] expr)
|
返回查询到的数据的 最小值,不是数字没有意义
|
案例:
- COUNT函数
统计班级中现在有多少名学生:
select count(*) from students;
- SUM函数
统计学号之和:
- AVG函数
统计平均学号:
select avg(id) 平均学号 from students;
- MAX函数
返回学号最大值:
select max(id) from students;
- MIN函数
返回学号最小值:
select min(id) from students;
7. group by子句的使用
在select中使用group by可以对指定列进行分组查询
select column1, column2, .. from table group by column;
案例:
- 准备工作,创建一个雇员信息表
EMP员工表
DEPT部门表
SALGRADE工资等级表
- 如何显示每个部门的平均工资和最高工资
select deptno,avg(sal),max(sal) from EMP group by deptno;
- 显示每个部门的每种岗位的平均工资和最低工资
select avg(sal),min(sal),job, deptno from EMP group by deptno, job;
- 显示平均工资低于2000的部门和它的平均工资
统计每个部门的平均工资:
select avg(sal) from EMP group by deptno
having和group by配合使用,对group by结果进行过滤
select avg(sal) as myavg from EMP group by deptno having myavg<2000;
--having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where
感谢各位大佬观看,创作不易,还望各位大佬点赞支持!!!