MySQL 基本查询与增删改查实战指南
在数据库开发中,数据的增删查改(CRUD)是最基础也是最核心的操作。本文将系统讲解 MySQL 的基本查询语句,深入探讨如何通过 SQL 高效、准确地对数据进行检索和处理。
一、Create:数据插入与替换
虽然 INSERT 语句大家比较熟悉,但了解 REPLACE 的机制同样重要。REPLACE 本质上是一种带有冲突检测的插入操作。
1.1 替换逻辑
当执行 REPLACE INTO 时,如果目标表中存在主键或唯一索引冲突的数据,MySQL 会先删除旧记录,再插入新记录;如果没有冲突,则直接插入。
-- 无冲突,直接插入
REPLACE INTO table_name (col1, col2) VALUES ('val1', 'val2');
-- 有冲突,先删后插
REPLACE INTO table_name (id, name) VALUES (1, 'NewName');
注意观察返回的行数影响:
1 row affected:表示没有冲突,仅插入。2 row affected:表示有冲突,删除旧行并插入新行。
二、Retrieve:数据检索详解
SELECT 是查询的核心。除了基础的字段选择,掌握高级用法能显著提升查询效率。
2.1 SELECT 列的选择
全列查询
使用 SELECT * 可以快速获取所有列,但在生产环境中需谨慎。因为查询列越多,网络传输数据量越大,且可能阻碍索引优化。
SELECT * FROM exam_result;
指定列查询
只查询需要的字段,减少 IO 开销。
SELECT name, english FROM exam_result;
表达式计算
SELECT 子句支持数学运算和字符串处理,结果会作为临时列返回。
-- 计算总分
SELECT chinese + math + english AS total_score FROM exam_result;
别名与去重
为计算结果指定别名能让输出更清晰。若需去除重复值,可使用 DISTINCT。
-- 指定别名
SELECT chinese + math + english AS total FROM exam_result;
-- 去重
SELECT DISTINCT math FROM exam_result;
2.2 WHERE 条件筛选
WHERE 子句用于过滤数据。常用的运算符包括比较运算符、逻辑运算符以及模糊匹配。
比较与逻辑运算
支持 =, >, <, >=, <=, <> 等。逻辑上支持 AND, OR, NOT。
-- 英语不及格
SELECT name, english FROM exam_result WHERE english < 60;
-- 语文成绩在 80 到 90 之间
SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;
-- 数学成绩为特定值之一
SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);
模糊查询
使用 LIKE 配合通配符 %(任意多个字符)和 _(单个字符)进行模式匹配。
-- 姓孙的同学
SELECT * FROM exam_result WHERE name LIKE '孙%';
-- 名字两个字且姓孙
SELECT * FROM exam_result WHERE name LIKE '孙_';
注意: 别名不能在 WHERE 中使用,因为 WHERE 的执行优先级高于 SELECT。此时应直接使用原始表达式。
2.3 结果排序与分页
排序 (ORDER BY)
默认升序 (ASC),降序需显式指定 (DESC)。多列排序时,按从左到右的优先级依次排列。
-- 按数学成绩降序
SELECT * FROM exam_result ORDER BY math DESC;
-- 多列排序:数学降序,英语升序
SELECT * FROM exam_result ORDER BY math DESC, english ASC;
*提示:NULL 值在排序时通常被视为最小值,升序排最前,降序排最后。
分页 (LIMIT)
LIMIT 用于限制返回行数,常用于分页查询。
-- 取前 3 条
SELECT * FROM exam_result LIMIT 3;
-- 从第 2 条开始,取 3 条 (偏移量为 2)
SELECT * FROM exam_result LIMIT 2, 3;
-- 推荐写法:OFFSET 明确偏移量
SELECT * FROM exam_result LIMIT 3 OFFSET 2;
三、Update:数据更新
使用 UPDATE 修改现有数据,务必配合 WHERE 条件,防止误更新全表。
-- 修改孙悟空的数学成绩
UPDATE exam_result SET math = 80 WHERE name = '孙悟空';
-- 同时修改多列
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
-- 复杂更新:总成绩倒数前三加 30 分
UPDATE exam_result
SET math = math + 30
WHERE id IN (
SELECT id FROM (
SELECT id FROM exam_result ORDER BY (chinese+math+english) ASC LIMIT 3
) AS temp
);
注意:MySQL 不支持 += 这种语法,必须写成 column = column + value。
四、Delete:数据删除
删除数据分为物理删除和截断表两种场景。
4.1 DELETE vs TRUNCATE
DELETE 可以带条件删除部分数据,但不会重置自增 ID (AUTO_INCREMENT)。
DELETE FROM exam_result WHERE name = '孙悟空';
TRUNCATE 清空整张表,速度快,且会重置自增 ID,但它无法回滚,也不能针对部分数据操作。
TRUNCATE TABLE exam_result;
五、聚合函数
聚合函数用于对一组数据进行统计计算。
COUNT(): 统计行数。SUM(): 求和。AVG(): 平均值。MAX()/MIN(): 最大/最小值。
-- 统计总人数
SELECT COUNT(*) FROM exam_result;
-- 统计去重后的分数个数
SELECT COUNT(DISTINCT math) FROM exam_result;
-- 获取最高分
SELECT MAX(english) FROM exam_result;
-- 大于 70 分的最低数学分
SELECT MIN(math) FROM exam_result WHERE math > 70;
六、GROUP BY 分组查询
GROUP BY 将数据分组,常配合聚合函数使用。HAVING 用于过滤分组后的结果。
6.1 分组与筛选
WHERE 在分组前执行,HAVING 在分组后执行。
-- 显示每个部门的平均工资
SELECT deptno, AVG(salary)
FROM emp
GROUP BY deptno;
-- 筛选平均工资低于 2000 的部门
SELECT deptno, AVG(salary)
FROM emp
GROUP BY deptno
HAVING AVG(salary) < 2000;
关键点: 不要试图在 WHERE 中对聚合结果进行筛选,那是 HAVING 的职责。理解两者的执行顺序对于编写正确的 SQL 至关重要。
掌握这些基础查询技巧,能够应对绝大多数日常数据处理需求。在实际开发中,结合具体业务场景灵活运用,才能写出既高效又易维护的 SQL 语句。


