MySQL 学习笔记(第三期):SQL 语言之数据操作与单表查询

MySQL 学习笔记(第三期):SQL 语言之数据操作与单表查询

本笔记承接第二期,进入数据操作(DML)和单表查询(DQL)的核心内容。涵盖:插入(INSERT)、更新(UPDATE)、删除(DELETE)数据,以及强大的 SELECT 查询语句,包括条件过滤、分组聚合、排序、分页等。所有代码均加以整理和注释。


一、DML 语句:数据操纵语言

DML 用于对表中的数据进行增加、修改、删除操作。

1.1 插入数据(INSERT)

基本语法

sql

复制代码
INSERT [INTO] tbl_name [(col1, col2, ...)] VALUES (val1, val2, ...), (val1, val2, ...), ...;

范例表(后续所有操作基于此表):

sql

复制代码
-- 创建测试表 stu
CREATE TABLE stu (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    age TINYINT UNSIGNED,
    gender ENUM('M','F') DEFAULT 'M',
    is_del BOOL DEFAULT FALSE
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
插入单条记录

sql

复制代码
-- 方式1:给出所有字段值(顺序与表定义一致)
INSERT INTO stu VALUES(10, 'xiaoming', 20, 'M', 0);

-- 方式2:只给部分字段,其他使用默认值或 NULL
INSERT INTO stu (name, age) VALUES ('xiaohong', 18);   -- gender 默认 'M',is_del 默认 0
插入多条记录

sql

复制代码
INSERT INTO stu (name, age) VALUES 
    ('test1', 20),
    ('test2', 21),
    ('test3', 22);
使用默认值或 NULL

sql

复制代码
-- age 和 gender 有默认值或允许 NULL
INSERT INTO stu (age, is_del) VALUES (23, 0);
如果记录存在则更新(ON DUPLICATE KEY UPDATE)

sql

复制代码
-- 假设 id=12 已存在,则更新 name 为 'zhangsan';否则插入新记录
INSERT INTO stu (id, name) VALUES (12, 'zhangsan')
ON DUPLICATE KEY UPDATE name = 'zhangsan';
将查询结果插入到表中

sql

复制代码
-- 从原表复制数据到另一张表(字段必须匹配)
INSERT INTO stu (name, age, gender)
SELECT name, age, gender FROM stu WHERE id = 11;

1.2 更新数据(UPDATE)

语法

sql

复制代码
UPDATE tbl_name SET col1 = val1, col2 = val2 ... [WHERE condition];

⚠️ 重要 :如果不加 WHERE 条件,将更新表中所有记录!生产环境务必小心。

无条件更新(全表更新)

sql

复制代码
UPDATE stu SET age = 30, gender = 'F';   -- 所有记录年龄改为 30,性别改为 F
条件更新

sql

复制代码
-- 单条件
UPDATE stu SET age = 31 WHERE id > 15;

-- 多条件(OR)
UPDATE stu SET age = 21, gender = 'M' WHERE id = 15 OR name IS NULL;

-- 多条件(AND)
UPDATE stu SET age = 22, gender = 'M' WHERE id = 17 AND name IS NULL;
安全更新模式(防止误操作)

sql

复制代码
-- 启动安全更新模式(要求 WHERE 条件必须使用索引列)
mysql -U
# 或在配置文件 /etc/my.cnf.d/client.cnf 中添加 safe-updates

-- 以下语句会被拒绝,因为没有使用主键条件
UPDATE stu SET age = 22;                     -- ERROR 1175
UPDATE stu SET age = 23 WHERE name = 'test3'; -- ERROR 1175(name 不是索引)

-- 只有使用主键条件才能执行
UPDATE stu SET age = 23 WHERE id = 17;       -- OK

1.3 删除数据(DELETE)

语法

sql

复制代码
DELETE FROM tbl_name [WHERE condition];

⚠️ 同样重要:不加 WHERE 会删除表中所有数据。

条件删除

sql

复制代码
DELETE FROM stu WHERE id = 10;
逻辑删除(推荐生产环境使用)

为避免物理删除导致数据不可恢复,通常增加一个"删除标记"字段,用 UPDATE 代替 DELETE。

sql

复制代码
-- 添加标记字段(已有 is_del)
ALTER TABLE stu ADD is_del BOOL DEFAULT FALSE;

-- 逻辑删除:将标记设为 1 表示已删除
UPDATE stu SET is_del = 1 WHERE id = 11;

-- 查询时只取未删除的记录
SELECT * FROM stu WHERE is_del = 0;
清空表

sql

复制代码
TRUNCATE TABLE tbl_name;   -- DDL 语句,速度快,不可回滚,自增列重置
DELETE FROM tbl_name;      -- DML 语句,可回滚,自增列不重置

二、DQL 语句:数据查询语言(单表查询)

SELECT 是 SQL 中最复杂的语句,用于从表中检索数据。

2.1 基本查询

sql

复制代码
SELECT col1, col2, ... FROM tbl_name [WHERE condition];
查询常量、表达式、函数

sql

复制代码
SELECT 123;                    -- 常量
SELECT 'gqd' AS 'laogao';      -- 字符串别名
SELECT 1+2*3;                  -- 表达式
SELECT NOW();                  -- 函数
SELECT VERSION();              -- 版本函数
查询所有字段

sql

复制代码
SELECT * FROM stu;
查询指定字段(可设置别名)

sql

复制代码
SELECT id AS 学号, name AS 姓名, age AS 年纪 FROM stu;

2.2 WHERE 条件过滤

比较运算符
运算符 含义
= 等于
<>!= 不等于
> , >= , < , <= 大小比较
BETWEEN ... AND ... 范围之间(包含边界)
IN (set) 匹配集合中的任意一个
LIKE 模糊匹配(% 任意长度,_ 单个字符)
IS NULL 空值判断
逻辑运算符
运算符 含义
AND (&&)
OR (||)
NOT (!)
范例

sql

复制代码
-- 等值条件
SELECT id, name FROM stu WHERE id = 11;

-- 多值匹配(IN)
SELECT id, name FROM stu WHERE id IN (11, 15, 19);

-- 范围匹配
SELECT id, name FROM stu WHERE id BETWEEN 12 AND 15;

-- 取反
SELECT id, name FROM stu WHERE id NOT BETWEEN 12 AND 15;
SELECT id, name FROM stu WHERE id NOT IN (12, 15, 19);

-- 组合条件
SELECT id, name FROM stu WHERE id >= 11 AND id < 14;
SELECT id, name FROM stu WHERE id <= 12 OR id > 19;

-- NULL 判断(注意不能用 = NULL)
SELECT id, name FROM stu WHERE name IS NULL;
SELECT id, name FROM stu WHERE name IS NOT NULL;

-- 模糊匹配
SELECT id, name FROM stu WHERE name LIKE 'x%';      -- 以 x 开头
SELECT id, name FROM stu WHERE name LIKE '%ng';     -- 以 ng 结尾
SELECT id, name FROM stu WHERE name LIKE '%n%';     -- 包含 n

2.3 聚合函数与分组(GROUP BY)

聚合函数对一组值进行计算并返回单个值。

函数 说明
COUNT(*) 统计记录数(包括 NULL)
COUNT(col) 统计某列非 NULL 值的个数
SUM(col) 求和
AVG(col) 平均值
MAX(col) 最大值
MIN(col) 最小值

注意:聚合函数忽略 NULL 值(COUNT(*) 除外)。

统计总数

sql

复制代码
SELECT COUNT(*) AS total FROM stu;          -- 总记录数
SELECT COUNT(name) FROM stu;                -- name 非空数量
SELECT COUNT(id) FROM stu;                  -- 主键非空数量
最大值、最小值、平均值、求和

sql

复制代码
SELECT MAX(id), MIN(id), AVG(age), SUM(age) FROM stu;
分组统计(GROUP BY)

sql

复制代码
-- 按性别分组,统计每组人数
SELECT COUNT(*), gender FROM stu GROUP BY gender;

-- 按性别分组,计算总年龄和平均年龄
SELECT SUM(age), AVG(age), gender FROM stu GROUP BY gender;
分组前过滤(WHERE)与分组后过滤(HAVING)
  • WHERE:在分组前对原始记录进行过滤
  • HAVING:在分组后对聚合结果进行过滤

sql

复制代码
-- 先过滤掉 name 为 NULL 的记录,再分组
SELECT COUNT(*), MAX(id), AVG(age), gender 
FROM stu 
WHERE name IS NOT NULL 
GROUP BY gender;

-- 分组后只显示总数为 3 的分组
SELECT COUNT(*) AS total, MAX(id), AVG(age), gender 
FROM stu 
WHERE name IS NOT NULL 
GROUP BY gender 
HAVING total = 3;

规则SELECT 中出现的非聚合字段必须出现在 GROUP BY 子句中。

2.4 排序(ORDER BY)

sql

复制代码
SELECT * FROM stu ORDER BY col1 [ASC|DESC], col2 [ASC|DESC], ...;
  • ASC:升序(默认)
  • DESC:降序

sql

复制代码
-- 按 id 升序
SELECT id, name, age FROM stu ORDER BY id;

-- 按 id 降序
SELECT id, name, age FROM stu ORDER BY id DESC;

-- 先按年龄降序,再按 id 升序
SELECT id, name, age FROM stu ORDER BY age DESC, id ASC;

2.5 去除重复行(DISTINCT)

sql

复制代码
SELECT DISTINCT age FROM stu ORDER BY age DESC;
SELECT DISTINCT(age) FROM stu;   -- 括号可选

2.6 分页查询(LIMIT)

sql

复制代码
SELECT * FROM tbl_name LIMIT [offset,] row_count;
  • offset:跳过的行数(从 0 开始)
  • row_count:返回的行数

sql

复制代码
-- 第一页,每页 3 条
SELECT id, name FROM stu LIMIT 0, 3;

-- 第二页,每页 3 条
SELECT id, name FROM stu LIMIT 3, 3;

-- 第三页,每页 3 条
SELECT id, name FROM stu LIMIT 6, 3;

三、综合范例演练

基于以下数据(stu 表),请尝试写出查询语句。

sql

复制代码
-- 查看全部数据
SELECT * FROM stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 11 | xiaohong | 30   | F      | 1      |
| 12 | zhangsan | 30   | F      | 0      |
| 13 | xiaozhou | 30   | F      | 1      |
| 14 | test1    | 30   | F      | 1      |
| 15 | test2    | 21   | M      | 1      |
| 16 | test3    | 31   | F      | 1      |
| 17 | NULL     | 23   | F      | 0      |
| 18 | xiaohong | 31   | F      | 1      |
| 19 | xiaohong | 31   | F      | 1      |
| 20 | zhangsan | 31   | F      | 1      |
+----+----------+------+--------+--------+

查询练习

sql

复制代码
-- 1. 查询所有女性(gender='F')且年龄大于等于 30 的姓名和年龄
SELECT name, age FROM stu WHERE gender = 'F' AND age >= 30;

-- 2. 统计男女各自的人数
SELECT gender, COUNT(*) FROM stu GROUP BY gender;

-- 3. 查询年龄最大的前 3 名(按年龄降序,取前3)
SELECT name, age FROM stu ORDER BY age DESC LIMIT 3;

-- 4. 查询名字中包含 'hong' 的所有记录
SELECT * FROM stu WHERE name LIKE '%hong%';

-- 5. 查询未被逻辑删除(is_del=0)的记录
SELECT * FROM stu WHERE is_del = 0;

四、本期知识点归纳一览表

类别 知识点 关键语法/命令
插入数据 单条/多条插入,指定字段,默认值 INSERT INTO ... VALUES ...
存在则更新 ON DUPLICATE KEY UPDATE
查询结果插入 INSERT ... SELECT ...
更新数据 条件更新,全表更新(慎用) UPDATE ... SET ... WHERE ...
安全更新模式 --safe-updates 或配置 safe-updates
删除数据 条件删除,逻辑删除(推荐) DELETE FROM ... WHERE ...
清空表 TRUNCATE TABLE vs DELETE FROM
基本查询 常量/表达式/函数查询 SELECT NOW();
字段别名 col AS alias
条件过滤 比较运算符 =, <>, >, <, BETWEEN, IN
逻辑运算符 AND, OR, NOT
空值判断 IS NULL, IS NOT NULL
模糊匹配 LIKE (%, _)
聚合与分组 聚合函数 COUNT, SUM, AVG, MAX, MIN
分组 GROUP BY
分组后过滤 HAVING
排序 升序/降序 ORDER BY ... ASC/DESC
去重 去除重复行 SELECT DISTINCT ...
分页 限制返回行数 LIMIT offset, row_count

下一期预告:SQL 语言之多表查询(内连接、外连接、自连接、子查询、联合查询,含王者荣耀实战案例)。

相关推荐
是上好佳佳佳呀5 分钟前
【LangChain|Day03】LangChain 链式调用 Chains 笔记
笔记·langchain
12点一刻6 分钟前
Hermes Agent 与 Superpowers 框架的区别?
运维·服务器
ZStack开发者社区10 分钟前
ZSTACK · 答客问 | 什么时候该升级,什么时候再等等
网络·云计算
北顾笙98019 分钟前
MYSQL-day03
数据库·sql·mysql
MXsoft61819 分钟前
**混合云统一监控实践:私有云+公有云的一体化运维方案**
运维·网络·数据库
2501_9127840822 分钟前
Taocarts深度解析:1688自动代采模块的Puppeteer自动化实战
运维·自动化
天南散修25 分钟前
MT7916驱动中802.11转换为802.3
linux·网络·驱动开发·wifi·802.11
MXsoft61825 分钟前
**断网续传与本地缓存:弱网环境下的监控数据保障方案**
运维·缓存·自动化
H__Rick26 分钟前
C51学习-DAY4
嵌入式硬件·学习·51单片机·硬件工程
LT101579744437 分钟前
2026年UI自动化测试平台选型指南:全界面自动化覆盖方案
运维·ui·自动化