一、核心查询能力
1.1 选择全部列与特定列
在 MySQL 中,最基础也是最常用的操作是使用 SELECT 语句从一个或多个表读取数据。SELECT 可以选择全部列,也可以限定要返回的列集合,FROM 指定数据源。现在我们先看两个简单示例,明确如何获取数据。
在本节中,我们回答 在 MySQL 中如何使用 SQL 语句查询和筛选数据?实战指南与常用查询示例,帮助读者理解基础与进阶用法。
SELECT * FROM users;
SELECT id, username, email FROM users;
第一条会返回 users 表的所有列,第二条只返回 id、username、email,这有助于减少网络传输和提高查询效率。
1.2 使用别名提高可读性
在复杂查询中,给表和列使用别名可以显著提升可读性,AS 关键字或空格都可用来定义别名。别名 让输出字段名更易理解,尤其在连接查询中更是如此。
SELECT u.id AS user_id, u.name AS user_name
FROM users AS u;
注意别名仅影响结果的列名展示,语义不变,但它有利于后续的 JOIN 或 子查询 编写。
二、筛选数据的核心条件
2.1 使用 WHERE 进行条件筛选
要从数据源中筛选符合条件的记录,WHERE 子句是核心。条件可以是简单的等值、范围比较,也可以结合逻辑运算符。实现前述需求时,优先选择 索引 所在的列以提升性能。
SELECT id, name, status
FROM users
WHERE status = 'active' AND created_at >= '2024-01-01';
此查询仅返回状态为 active 且创建日期在 2024-01-01 之后的记录,逻辑组合应与业务需求相匹配。
2.2 逻辑运算符与数据类型
在条件表达式中,AND、OR、NOT 用于组合多个条件,数据类型 的正确处理是关键。不同数据类型的比较规则会影响索引的使用与结果集的准确性。
SELECT id, name
FROM products
WHERE price BETWEEN 100 AND 500AND stock > 0AND category IN ('electronics', 'appliances');
通过 BETWEEN、IN 等运算符可以简化条件表达式,提升可读性并帮助数据库优化器决定最优执行计划。
三、排序、分页与取样
3.1 ORDER BY 的排序方式
排序是数据展现的常见需求,ORDER BY 指定一个或多个列及排序方向。合理的排序顺序能显著提升用户体验,并且在某些场景有助于使用 索引。
SELECT id, name, created_at
FROM posts
ORDER BY created_at DESC, id ASC
LIMIT 50;
示例中,结果先按 created_at 值降序排序,若相同再以 id 升序排序,最终限制返回前 50 条记录。
3.2 LIMIT 与分页
分页查询常用于大量数据的展示,LIMIT 可结合偏移量实现分页。合理的分页策略能提升响应速度并降低服务器负载。
-- 第1页,每页10条
SELECT id, title
FROM articles
ORDER BY published_at DESC
LIMIT 0, 10;-- 第2页
SELECT id, title
FROM articles
ORDER BY published_at DESC
LIMIT 10, 10;
注意偏移量与总数据量的关系,分页策略应结合业务场景进行优化。
四、聚合查询与分组
4.1 使用聚合函数
聚合函数如 COUNT、SUM、AVG、MIN、MAX 常用于汇总分析。GROUP BY 将结果按某一列分组后再对每组执行聚合。

SELECT status, COUNT(*) AS total_orders, SUM(total) AS revenue
FROM orders
GROUP BY status;
status 的每一个不同值都会得到一组聚合结果,total_orders 表示该状态下的订单数量,revenue 是该状态的总金额。
4.2 HAVING 过滤聚合结果
对于聚合结果的筛选,不能使用 WHERE,而应使用 HAVING。它对聚合结果进行条件判断,常用于过滤太小的分组。
SELECT status, COUNT(*) AS total_orders
FROM orders
GROUP BY status
HAVING COUNT(*) > 100;
上述查询仅返回订单数量超过 100 的状态分组,HAVING 在聚合查询中具有独立意义。
五、连接查询与多表检索
5.1 内连接(INNER JOIN)
多表检索通常依赖 JOIN,其中 INNER JOIN 只返回在两张表中都有匹配的记录。使用别名可以让条件更清晰。
SELECT u.id AS user_id, u.name, o.order_id, o.total
FROM users AS u
INNER JOIN orders AS o ON u.id = o.user_id
WHERE o.status = 'completed'
ORDER BY o.created_at DESC
LIMIT 20;
此查询通过 ON 指定连接条件,确保仅返回有购买记录的用户信息,匹配条件直接决定结果集。
5.2 左/右连接的用法
除了内部连接,LEFT JOIN(左连接)和 RIGHT JOIN(右连接)可以保留一张表中的全部记录,同时把另一表的匹配项填充为 NULL。
SELECT p.id, p.name, c.category_name
FROM products AS p
LEFT JOIN categories AS c ON p.category_id = c.id
ORDER BY p.id ASC
LIMIT 10;
左连接确保即使某些产品没有分类,也能看到产品信息,NULL 表示缺失的关联数据。
六、子查询与复杂查询
6.1 相关子查询
子查询可以放在 SELECT、FROM 或 WHERE 子句中。相关子查询是指外部查询的字段会作为内层查询的条件依赖。
SELECT id, name
FROM users AS u
WHERE EXISTS (SELECT 1FROM orders AS oWHERE o.user_id = u.id AND o.total > 100
);
通过 EXISTS 可以判断是否存在符合条件的相关子记录,效率通常较高,尤其对大数据表。
6.2 EXISTS、IN 的用法
IN 与 EXISTS 都可用于子查询的过滤,IN 直接比较一个值集,EXISTS 则在找到第一条匹配后即返回,通常二者在不同场景下有不同性能表现。
SELECT id, name
FROM users
WHERE id IN (SELECT user_id FROM orders WHERE total > 100);
SELECT id, name
FROM users u
WHERE EXISTS (SELECT 1FROM orders oWHERE o.user_id = u.id AND o.status = 'shipped'
);
结合实际数据分布,IN 更直观,EXISTS 在大量子查询结果时往往更高效。


