SELECT
1、 基础查询
查询所有字段
-- 查询 employees 表的所有数据
SELECT * FROM employees;
注意:在生产环境中,除非必要,否则不建议使用 *,因为会传输多余数据并可能影响索引效率。
查询指定字段
只获取需要的列,减少网络传输开销。
-- 只查询姓名和年龄
SELECT name, age FROM students;
去除重复记录
使用 DISTINCT 关键字消除结果集中的重复行。
-- 查询所有不重复的部门ID
SELECT DISTINCT dept_id FROM employees;
使用别名
为列或表设置别名,使结果更易读或在多表查询中区分字段。
-- 使用 AS 关键字或直接空格"
SELECT name AS 姓名, age AS 年龄 FROM students;
SELECT s.name, s.age FROM students AS s;
2、条件过滤 (WHERE)
比较运算符
使用 =, >, <, >=, <=, != 进行精确或范围匹配。
-- 查询年龄大于 25 岁的员工
SELECT * FROM employees WHERE age > 25;
-- 查询部门ID为 1 的员工
SELECT * FROM employees WHERE dept_id = 1;
逻辑运算符 (AND, OR, NOT)
组合多个条件。
-- 查询年龄大于 25 且 部门ID为 1 的员工
SELECT * FROM employees WHERE age > 25 AND dept_id = 1;
-- 查询部门ID为 1 或 2 的员工
SELECT * FROM employees WHERE dept_id = 1 OR dept_id = 2;
范围查询 (BETWEEN ... AND)
查询某个连续区间内的值(包含边界值)。
-- 查询年龄在 20 到 30 岁之间的员工
SELECT * FROM employees WHERE age BETWEEN 20 AND 30;
列表查询 (IN)
匹配指定集合中的任何一个值。
-- 查询部门ID为 1, 3, 5 的员工
SELECT * FROM employees WHERE dept_id IN (1, 3, 5);
模糊查询 (LIKE)
使用 DISTINCT 关键字消除结果集中的重复行。
-- 查询姓“张”的学生(如:张三、张学友)
SELECT * FROM students WHERE name LIKE '张%';
-- 查询名字中第二个字是“学”的学生(如:张学友)
SELECT * FROM students WHERE name LIKE '_学%';
-- 查询名字中包含“伟”的学生
SELECT * FROM students WHERE name LIKE '%伟%';
空值查询 (IS NULL / IS NOT NULL)
判断字段是否为空。
-- 查询邮箱未知的用户
SELECT * FROM users WHERE email IS NULL;
-- 查询QQ号已知的用户
SELECT * FROM users WHERE qq IS NOT NULL;
3、排序与限制
结果排序 (ORDER BY)
默认升序 (ASC),可指定降序 (DESC)。
-- 按年龄升序排列
SELECT * FROM students ORDER BY age ASC;
-- 按数学成绩降序排列,如果成绩相同则按英语成绩升序
SELECT * FROM scores ORDER BY math DESC, english ASC;
分页限制 (LIMIT)
使用 DISTINCT 关键字消除结果集中的重复行。
-- 只返回前 5 条记录
SELECT * FROM employees LIMIT 5;
-- 从第 11 条记录开始,返回 10 条记录(即第2页,每页10条)
-- 语法: LIMIT offset, count
SELECT * FROM employees LIMIT 10, 10;
4、聚合与分组
常用聚合函数
- COUNT(): 统计行数
- SUM(): 求和
- AVG(): 平均值
- MAX(): 最大值
- MIN(): 最小值
-- 统计员工总数
SELECT COUNT(*) FROM employees;
-- 计算平均年龄
SELECT AVG(age) FROM employees;
分组查询 (GROUP BY)
将数据按某列分组,通常配合聚合函数使用。
-- 统计每个部门的员工人数
SELECT dept_id, COUNT(*) AS emp_count
FROM employees
GROUP BY dept_id;
分组后过滤 (HAVING)
WHERE 过滤行,HAVING 过滤分组后的结果。
-- 统计每个部门的员工人数,只显示人数大于 5 的部门
SELECT dept_id, COUNT(*) AS emp_count
FROM employees
GROUP BY dept_id
HAVING emp_count > 5;
5、多表连接 (JOIN)
当数据分布在多个表中时,使用 JOIN 进行关联查询。
内连接 (INNER JOIN)
只返回两个表中联结字段相等的行。
-- 查询学生姓名及其对应的班级名称
SELECT s.name, c.class_name
FROM students s
INNER JOIN classes c ON s.class_id = c.id;
左连接 (LEFT JOIN)
返回左表所有行,即使右表中没有匹配。
-- 查询所有学生及其班级,即使某些学生未分配班级
SELECT s.name, c.class_name
FROM students s
LEFT JOIN classes c ON s.class_id = c.id;
右连接 (RIGHT JOIN)
返回右表所有行,即使左表中没有匹配。
-- 查询所有学生及其班级,即使某些学生未分配班级
SELECT s.name, c.class_name
FROM students s
RIGHT JOIN classes c ON s.class_id = c.id;
6、子查询 (Subquery)
将一个查询的结果作为另一个查询的条件或数据源。
WHERE 子句中的子查询
-- 查询工资高于平均工资的员工
SELECT * FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
FROM 子句中的子查询(派生表)
-- 查询每个部门的最高工资,并将结果作为临时表再次查询
SELECT * FROM (
SELECT dept_id, MAX(salary) as max_sal
FROM employees
GROUP BY dept_id
) AS dept_max_salaries;
💡 最佳实践提示
- 避免 SELECT *:明确指定需要的列,提高性能。:
- 索引优化: 确保 WHERE、ORDER BY 和 JOIN 中的字段上有适当的索引
- 执行顺序: SQL 的逻辑执行顺序是 FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT,理解这一点有助于编写正确的复杂查询。

浙公网安备 33010602011771号