MySQL表的增删改查(CRUD)操作详解

1. 什么是CRUD

CRUD是数据库操作的四个基本功能:

  • **Create(创建)**​ - 插入数据

  • **Retrieve(读取)**​ - 查询数据

  • **Update(更新)**​ - 更新数据

  • **Delete(删除)**​ - 删除数据

2. Create - 数据插入

2.1 基本语法

复制代码
INSERT [INTO] table_name [(column[, column]...)] 
VALUES (value_list)[, (value_list)]...

2.2 创建示例表

复制代码
CREATE TABLE students (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    sn INT NOT NULL UNIQUE COMMENT '学号',
    name VARCHAR(20) NOT NULL,
    qq VARCHAR(20)
);

2.3 单行数据全列插入

复制代码
-- 插入两条记录,value_list数量必须和定义表的列的数量及顺序一致
INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
INSERT INTO students VALUES (101, 10001, '孙悟空', '11111');

2.4 多行数据指定列插入

复制代码
-- 插入两条记录,value_list数量必须和指定列数量及顺序一致
INSERT INTO students (id, sn, name) VALUES 
(102, 20001, '曹孟德'),
(103, 20002, '孙仲谋');

2.5 插入否则更新

当主键或唯一键冲突时,可以选择更新操作:

复制代码
INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师')
ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大师';

返回值说明:

  • 0 row affected:表中有冲突数据,但冲突数据的值和update的值相等

  • 1 row affected:表中没有冲突数据,数据被插入

  • 2 row affected:表中有冲突数据,并且数据已经被更新

2.6 替换操作

复制代码
REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');

返回值说明:

  • 1 row affected:表中没有冲突数据,数据被插入

  • 2 row affected:表中有冲突数据,删除后重新插入

3. Retrieve - 数据查询

3.1 基本语法

复制代码
SELECT
    [DISTINCT] {* | {column [, column] ...}}
    [FROM table_name]
    [WHERE ...]
    [ORDER BY column [ASC | DESC], ...]
    [LIMIT ...]

3.2 创建测试表

复制代码
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);

3.3 查询类型

3.3.1 全列查询
复制代码
SELECT * FROM exam_result;

注意: ​ 不建议使用*进行全列查询,因为查询的列越多,传输的数据量越大,可能影响索引使用。

3.3.2 指定列查询
复制代码
SELECT id, name, english FROM exam_result;
3.3.3 查询字段为表达式
复制代码
-- 表达式不包含字段
SELECT id, name, 10 FROM exam_result;

-- 表达式包含一个字段
SELECT id, name, english + 10 FROM exam_result;

-- 表达式包含多个字段
SELECT id, name, chinese + math + english FROM exam_result;
3.3.4 为查询结果指定别名
复制代码
SELECT id, name, chinese + math + english AS 总分 FROM exam_result;
3.3.5 结果去重
复制代码
-- 去重前
SELECT math FROM exam_result;

-- 去重后
SELECT DISTINCT math FROM exam_result;

3.4 WHERE条件查询

比较运算符
运算符 说明
>, >=, <, <= 大于,大于等于,小于,小于等于
= 等于,NULL不安全
<=> 等于,NULL安全
!=, <> 不等于
BETWEEN a0 AND a1 范围匹配,[a0,a1]
IN (option, ...) 如果是option中的任意一个,返回TRUE
IS NULL 是NULL
IS NOT NULL 不是NULL
LIKE 模糊匹配(%表示任意多个字符,_表示任意一个字符)
逻辑运算符
运算符 说明
AND 多个条件必须都为TRUE,结果才是TRUE
OR 任意一个条件为TRUE,结果为TRUE
NOT 条件为TRUE,结果为FALSE
查询示例

1. 英语不及格的同学

复制代码
SELECT name, english FROM exam_result WHERE english < 60;

2. 语文成绩在[80,90]分的同学

复制代码
-- 使用AND
SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese <= 90;

-- 使用BETWEEN
SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;

3. 数学成绩是58,59,98,99分的同学

复制代码
-- 使用OR
SELECT name, math FROM exam_result 
WHERE math = 58 OR math = 59 OR math = 98 OR math = 99;

-- 使用IN
SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);

4. 姓孙的同学

复制代码
-- 孙% 匹配姓孙的同学
SELECT name FROM exam_result WHERE name LIKE '孙%';

-- 孙_ 匹配姓孙且名字为两个字的同学
SELECT name FROM exam_result WHERE name LIKE '孙_';

5. 语文成绩好于英语成绩的同学

复制代码
SELECT name, chinese, english FROM exam_result WHERE chinese > english;

6. 总分在200分以下的同学

复制代码
SELECT name, chinese + math + english AS 总分 
FROM exam_result 
WHERE chinese + math + english < 200;

7. 语文成绩>80并且不姓孙的同学

复制代码
SELECT name, chinese FROM exam_result 
WHERE chinese > 80 AND name NOT LIKE '孙%';

8. NULL查询

复制代码
-- 查询qq号已知的同学
SELECT name, qq FROM students WHERE qq IS NOT NULL;

-- NULL和NULL的比较
SELECT NULL = NULL, NULL = 1, NULL = 0;  -- 结果都是NULL
SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;  -- 结果: 1, 0, 0

3.5 排序查询

3.5.1 基本语法
复制代码
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC | DESC], [...];
3.5.2 排序示例

1. 按数学成绩升序显示

复制代码
SELECT name, math FROM exam_result ORDER BY math;

2. 按qq号排序显示

复制代码
-- NULL视为比任何值都小,升序出现在最上面
SELECT name, qq FROM students ORDER BY qq;

-- NULL视为比任何值都小,降序出现在最下面
SELECT name, qq FROM students ORDER BY qq DESC;

3. 多字段排序

复制代码
SELECT name, math, english, chinese FROM exam_result 
ORDER BY math DESC, english, chinese;

4. 按总分排序

复制代码
SELECT name, chinese + math + english AS 总分 
FROM exam_result 
ORDER BY 总分 DESC;

3.6 分页查询

3.6.1 基本语法
复制代码
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...]
LIMIT n OFFSET s;
3.6.2 分页示例
复制代码
-- 第1页:每页3条记录
SELECT id, name, math, english, chinese FROM exam_result 
ORDER BY id LIMIT 3 OFFSET 0;

-- 第2页
SELECT id, name, math, english, chinese FROM exam_result 
ORDER BY id LIMIT 3 OFFSET 3;

-- 第3页
SELECT id, name, math, english, chinese FROM exam_result 
ORDER BY id LIMIT 3 OFFSET 6;

4. Update - 数据更新

4.1 基本语法

复制代码
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]

4.2 更新示例

1. 将孙悟空同学的数学成绩变更为80分

复制代码
UPDATE exam_result SET math = 80 WHERE name = '孙悟空';

2. 将曹孟德同学的数学成绩变更为60分,语文成绩变更为70分

复制代码
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';

3. 将总成绩倒数前三的3位同学的数学成绩加上30分

复制代码
UPDATE exam_result SET math = math + 30
ORDER BY chinese + math + english LIMIT 3;

4. 将所有同学的语文成绩更新为原来的2倍

复制代码
UPDATE exam_result SET chinese = chinese * 2;

5. Delete - 数据删除

5.1 基本语法

复制代码
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]

5.2 删除示例

1. 删除孙悟空同学的考试成绩

复制代码
DELETE FROM exam_result WHERE name = '孙悟空';

2. 删除整张表数据

复制代码
-- 创建测试表
CREATE TABLE for_delete (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20)
);

-- 插入测试数据
INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');

-- 删除整表数据
DELETE FROM for_delete;

-- 再插入数据,自增id在原值上增长
INSERT INTO for_delete (name) VALUES ('D');  -- id为4

5.3 截断表

复制代码
TRUNCATE [TABLE] table_name;

TRUNCATE与DELETE的区别:

  1. 只能对整表操作,不能针对部分数据操作

  2. 比DELETE更快,但不经过事务,无法回滚

  3. 会重置AUTO_INCREMENT项

    TRUNCATE for_truncate; -- 自增id会重新从1开始

6. 插入查询结果

6.1 基本语法

复制代码
INSERT INTO table_name [(column [, column ...])] SELECT ...

6.2 删除重复记录示例

复制代码
-- 创建原数据表
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');

-- 创建空表
CREATE TABLE no_duplicate_table LIKE duplicate_table;

-- 插入去重后的数据
INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;

7. 聚合函数

函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的数量
SUM([DISTINCT] expr) 返回查询到的数据的总和
AVG([DISTINCT] expr) 返回查询到的数据的平均值
MAX([DISTINCT] expr) 返回查询到的数据的最大值
MIN([DISTINCT] expr) 返回查询到的数据的最小值

7.1 聚合函数示例

1. 统计班级共有多少同学

复制代码
SELECT COUNT(*) FROM students;

2. 统计班级收集的qq号有多少

复制代码
SELECT COUNT(qq) FROM students;  -- NULL不会计入结果

3. 统计数学成绩分数个数

复制代码
-- 全部成绩
SELECT COUNT(math) FROM exam_result;

-- 去重成绩数量
SELECT COUNT(DISTINCT math) FROM exam_result;

4. 统计数学成绩总分

复制代码
SELECT SUM(math) FROM exam_result;

5. 统计平均总分

复制代码
SELECT AVG(chinese + math + english) AS 平均总分 FROM exam_result;

6. 返回英语最高分

复制代码
SELECT MAX(english) FROM exam_result;

7. 返回>70分以上的数学最低分

复制代码
SELECT MIN(math) FROM exam_result WHERE math > 70;

8. GROUP BY子句使用

8.1 基本语法

复制代码
SELECT column1, column2, ... FROM table GROUP BY column;

8.2 分组查询示例

1. 显示每个部门的平均工资和最高工资

复制代码
SELECT deptno, AVG(sal), MAX(sal) FROM EMP GROUP BY deptno;

2. 显示每个部门的每种岗位的平均工资和最低工资

复制代码
SELECT AVG(sal), MIN(sal), job, deptno FROM EMP GROUP BY deptno, job;

3. 显示平均工资低于2000的部门和它的平均工资

复制代码
SELECT deptno, AVG(sal) AS myavg FROM EMP GROUP BY deptno HAVING myavg < 2000;

9. SQL关键字执行顺序

执行顺序:

FROM> ON> JOIN> WHERE> GROUP BY> WITH> HAVING> SELECT> DISTINCT> ORDER BY> LIMIT

相关推荐
老姚---老姚2 小时前
在windows下编译go语言编写的dll库
开发语言·windows·golang
定偶2 小时前
MySQL安装
数据库·mysql
Zzzzmo_2 小时前
【MySQL】数据库约束 及 表的设计
数据库·mysql
码云数智-大飞2 小时前
Oracle RAS:AI时代守护企业数据安全的智能盾牌
数据库·人工智能·oracle
bubuly2 小时前
软件开发全流程注意事项:从需求到运维的全方位指南
大数据·运维·数据库
love530love3 小时前
技术复盘:llama-cpp-python CUDA 编译实战 (Windows)
人工智能·windows·python·llama·aitechlab·cpp-python·cuda版本
我真的是大笨蛋3 小时前
Redo Log详解
java·数据库·sql·mysql·性能优化
fengxin_rou3 小时前
Redis 从零到精通:第一篇 初识redis
数据库·redis·缓存
爱学习的阿磊3 小时前
Python上下文管理器(with语句)的原理与实践
jvm·数据库·python