MySQL 的 SELECT 语句用于从数据库表中检索数据,是日常开发中使用频率最高的 SQL 语句之一。掌握不同场景下的操作实例,有助于理解查询条件的组合方式、结果集的排序分页逻辑以及多表关联的表达能力,从而提升数据查询效率。在实际业务中,一条查询往往不是简单的全表读取,而是由字段选择、条件过滤、排序控制、分组统计和表连接共同组成。

基础查询与数据准备
要理解 SELECT 语句,首先需要准备一张结构清晰的测试表。用户表通常包含主键、用户名、年龄和城市等字段,这些字段能够覆盖基础查询、条件过滤和分组统计的常见需求。主键用于唯一标识记录,字符串字段适合做等值匹配和模糊匹配,数值字段适合做范围比较和排序。
-- 创建用户表
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
age INT,
city VARCHAR(50)
);
-- 插入测试数据
INSERT INTO user (username, age, city) VALUES
('张三', 25, '北京'),
('李四', 30, '上海'),
('王五', 22, '广州'),
('赵六', 28, '北京');
最基础的查询是读取表中所有记录,也可以使用 SELECT 指定需要返回的字段。读取全部字段适合快速查看表结构或调试数据,但在正式业务中,通常只返回页面或接口真正需要的列。这样既能减少网络传输内容,也能让查询意图更加明确。
SELECT * FROM user; SELECT username, city FROM user;
从工程角度看,明确列出字段还有助于维护代码。当表结构发生变化时,依赖全部字段的查询更容易暴露问题;而只选择必要字段的查询则更稳定。对于初学者来说,先使用全部字段确认数据存在,再逐步改成指定字段,是理解查询行为的有效方式。
条件过滤与常用匹配方式
WHERE 子句用于在查询过程中加入过滤条件,只返回满足条件的记录。常见条件运算符包括 =、>、<、LIKE、IN 等。等值判断适合城市、状态等字段,比较运算适合年龄、金额等数值字段,模糊匹配则适合用户名、标题等文本字段。
SELECT * FROM user WHERE age > 25;
SELECT * FROM user WHERE city = '北京';
SELECT * FROM user WHERE age BETWEEN 22 AND 28;
SELECT * FROM user WHERE username LIKE '%三%';
SELECT * FROM user WHERE city IN ('北京', '上海');
BETWEEN 可以简化范围条件,LIKE 可以配合通配符进行模糊匹配。百分号代表任意多个字符,下划线代表单个字符。例如查询用户名中包含“三”的记录时,使用 %三% 就能匹配“张三”“王三”“三某”等不同写法。对于文本搜索,模糊匹配非常灵活,但条件越宽松,返回的数据量可能越大。
多个条件可以通过 AND、OR、NOT 组合,表达更复杂的业务规则。例如同时要求年龄大于 25 且城市为北京,或者城市属于北京、上海之一。使用括号可以明确优先级,避免逻辑判断出现偏差。理解条件组合是写好查询语句的重要基础。
SELECT * FROM user WHERE age > 25 AND city = '北京';
SELECT * FROM user WHERE city IN ('北京', '上海') AND age < 30;
排序、分页与结果集控制
ORDER BY 用于对查询结果排序,ASC 表示升序,DESC 表示降序,默认通常为升序。排序可以基于单个字段,也可以基于多个字段。当主排序字段出现相同值时,次级排序字段可以保证结果顺序更加稳定,这对分页展示尤其重要。
SELECT * FROM user ORDER BY age ASC; SELECT * FROM user ORDER BY age DESC, id ASC LIMIT 2;
LIMIT 用于限制返回行数,是实现分页的常用方式。每页显示固定数量数据时,可以先对结果排序,再跳过前面已经展示过的记录,取出当前页需要的记录。例如每页 2 条数据时,第 2 页可以跳过前 2 条,再取 2 条。
SELECT * FROM user ORDER BY age DESC LIMIT 2; SELECT * FROM user ORDER BY age ASC LIMIT 2, 2;
分页查询的关键在于排序和偏移量要配合使用。如果没有排序,数据库返回顺序可能不稳定,用户翻页时可能出现重复或遗漏。明确分页逻辑后,再结合业务需求选择每页数量,就能得到更可控的结果集。
分组统计与聚合过滤
GROUP BY 用于将数据按指定字段分组,再对每个分组执行统计。聚合函数如 COUNT、SUM、AVG 可以分别用于计数、求和和求平均值。分组查询常用于统计每个城市的用户数量、每个类别的订单总额、每个部门的平均薪资等场景。
SELECT city, COUNT(*) AS user_count FROM user GROUP BY city;
HAVING 用于对分组后的结果进行过滤。与 WHERE 不同,WHERE 通常在分组前过滤单条记录,HAVING 则针对分组统计后的结果进行判断。例如只保留用户数量大于 1 的城市,就需要先按城市分组并计数,再使用 HAVING 过滤分组结果。
SELECT city, COUNT(*) AS user_count FROM user GROUP BY city HAVING user_count > 1;
在分组查询中,非分组字段通常需要放入聚合函数中,否则查询含义会不清晰。例如统计城市用户数量时,返回城市字段和计数是合理的;如果直接返回用户名而没有聚合,就无法确定每个城市应该展示哪一个用户。理解这一规则,有助于避免常见语法错误。
多表关联与查询组合
实际开发中,数据经常分散在多张表中。用户表保存用户信息,订单表保存订单金额,查询某个用户的消费情况时需要把两张表关联起来。外键关系可以帮助维护表之间的对应关系,让连接查询具有明确的数据依据。
-- 创建订单表
CREATE TABLE order_table (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
order_amount DECIMAL(10,2),
FOREIGN KEY (user_id) REFERENCES user(id)
);
-- 插入测试订单数据
INSERT INTO order_table (user_id, order_amount) VALUES
(1, 199.99),
(1, 299.50),
(2, 150.00);
INNER JOIN 返回两张表中满足连接条件的记录。如果用户没有订单,该用户不会出现在结果中。这种连接适合查询“有订单的用户及其订单金额”这类场景。左连接 LEFT JOIN 则保留左表全部记录,当右表没有匹配记录时,右表字段显示为空,适合查询“所有用户及其订单金额”。
SELECT u.username, o.order_amount FROM user u INNER JOIN order_table o ON u.id = o.user_id; SELECT u.username, o.order_amount FROM user u LEFT JOIN order_table o ON u.id = o.user_id;
连表查询的核心是明确连接字段和连接方向。连接字段通常是主键和外键,连接方向则取决于业务希望保留哪一侧的数据。把基础查询、条件过滤、排序分页和分组统计与表连接结合起来,就能表达更复杂的业务查询需求。
总结与实用建议
MySQL 的 SELECT 语句看似简单,却覆盖了数据检索的大部分核心能力。从基础查询到条件过滤,从排序分页到分组统计,再到多表连接,每一步都在缩小结果集或扩展数据来源。理解这些实例的关键,不在于记忆语法,而在于明确每次查询要返回什么、过滤什么、按什么顺序展示以及如何组织多表数据。
在实际练习中,可以先从单表查询开始,确认字段和条件是否符合预期,再逐步加入排序、分页、分组和连接。遇到复杂查询时,可以拆分成多个小步骤验证:先查基础数据,再加 WHERE,再加 ORDER BY,最后加 GROUP BY 或 JOIN。通过这种由浅入深的方式,能够更稳定地掌握 SELECT 语句的操作实例。