Appearance
查询进阶
本章将介绍MySQL查询的高级用法,包括条件查询、排序、分组、聚合函数等内容。
基本查询
SELECT基础
sql
-- 创建示例表
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
department VARCHAR(50),
position VARCHAR(50),
salary DECIMAL(10, 2),
hire_date DATE,
status ENUM('active', 'inactive') DEFAULT 'active'
);
-- 插入测试数据
INSERT INTO employees (name, department, position, salary, hire_date, status) VALUES
('张三', '技术部', '工程师', 15000, '2020-01-15', 'active'),
('李四', '技术部', '高级工程师', 25000, '2018-06-01', 'active'),
('王五', '销售部', '销售经理', 20000, '2019-03-20', 'active'),
('赵六', '销售部', '销售员', 12000, '2021-07-10', 'active'),
('钱七', '人事部', 'HR', 10000, '2022-01-05', 'active'),
('孙八', '技术部', '工程师', 16000, '2020-08-15', 'inactive'),
('周九', '财务部', '会计', 14000, '2019-11-01', 'active'),
('吴十', '技术部', '架构师', 35000, '2017-01-01', 'active');
-- 查询所有列
SELECT * FROM employees;
-- 查询指定列
SELECT name, department, salary FROM employees;
-- 使用别名
SELECT
name AS 姓名,
department AS 部门,
salary AS 工资
FROM employees;
-- 表别名
SELECT e.name, e.department, e.salary
FROM employees AS e;DISTINCT去重
sql
-- 查询所有部门
SELECT department FROM employees;
-- 去重查询
SELECT DISTINCT department FROM employees;
-- 多列去重
SELECT DISTINCT department, position FROM employees;
-- 统计去重数量
SELECT COUNT(DISTINCT department) AS 部门数量
FROM employees;条件查询
WHERE子句
sql
-- 基本条件查询
SELECT * FROM employees WHERE department = '技术部';
-- 比较运算符
SELECT * FROM employees WHERE salary > 20000;
SELECT * FROM employees WHERE salary >= 20000;
SELECT * FROM employees WHERE salary < 15000;
SELECT * FROM employees WHERE salary <= 15000;
SELECT * FROM employees WHERE salary != 15000;
SELECT * FROM employees WHERE salary <> 15000; -- 不等于
-- 日期条件
SELECT * FROM employees WHERE hire_date > '2020-01-01';
SELECT * FROM employees WHERE hire_date BETWEEN '2020-01-01' AND '2021-12-31';
-- NULL值判断
SELECT * FROM employees WHERE department IS NULL;
SELECT * FROM employees WHERE department IS NOT NULL;逻辑运算符
sql
-- AND:同时满足多个条件
SELECT * FROM employees
WHERE department = '技术部' AND salary > 20000;
-- OR:满足任一条件
SELECT * FROM employees
WHERE department = '技术部' OR department = '销售部';
-- NOT:取反
SELECT * FROM employees
WHERE NOT department = '技术部';
-- 组合使用(注意优先级)
SELECT * FROM employees
WHERE (department = '技术部' OR department = '销售部')
AND salary > 15000;IN和BETWEEN
sql
-- IN:匹配列表中的值
SELECT * FROM employees
WHERE department IN ('技术部', '销售部');
-- NOT IN:不在列表中
SELECT * FROM employees
WHERE department NOT IN ('技术部', '销售部');
-- BETWEEN:范围查询(包含边界)
SELECT * FROM employees
WHERE salary BETWEEN 10000 AND 20000;
-- NOT BETWEEN
SELECT * FROM employees
WHERE salary NOT BETWEEN 10000 AND 20000;
-- 日期范围
SELECT * FROM employees
WHERE hire_date BETWEEN '2020-01-01' AND '2020-12-31';LIKE模糊查询
sql
/*
* LIKE通配符:
* % - 匹配任意多个字符
* _ - 匹配单个字符
*/
-- 以"张"开头
SELECT * FROM employees WHERE name LIKE '张%';
-- 以"三"结尾
SELECT * FROM employees WHERE name LIKE '%三';
-- 包含"工程"
SELECT * FROM employees WHERE position LIKE '%工程%';
-- 匹配单个字符
SELECT * FROM employees WHERE name LIKE '张_';
-- 组合使用
SELECT * FROM employees WHERE position LIKE '%工程%师';
-- 转义特殊字符
SELECT * FROM employees WHERE name LIKE '%\%%'; -- 查找包含%的名称
-- 使用ESCAPE指定转义字符
SELECT * FROM employees WHERE name LIKE '%@%%' ESCAPE '@';排序
ORDER BY
sql
-- 升序排序(默认)
SELECT * FROM employees ORDER BY salary;
-- 降序排序
SELECT * FROM employees ORDER BY salary DESC;
-- 多列排序
SELECT * FROM employees
ORDER BY department ASC, salary DESC;
-- 按列位置排序
SELECT name, salary FROM employees
ORDER BY 2 DESC; -- 按第2列(salary)排序
-- 按表达式排序
SELECT name, salary, salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;
-- NULL值排序(MySQL默认NULL最小)
SELECT * FROM employees ORDER BY salary IS NULL, salary DESC;自定义排序
sql
-- 使用FIELD函数自定义排序
SELECT * FROM employees
ORDER BY FIELD(department, '技术部', '销售部', '人事部', '财务部');
-- 使用CASE自定义排序
SELECT * FROM employees
ORDER BY
CASE department
WHEN '技术部' THEN 1
WHEN '销售部' THEN 2
WHEN '人事部' THEN 3
ELSE 4
END;分页查询
sql
/*
* LIMIT语法:
* LIMIT offset, count
* 或 LIMIT count OFFSET offset
*/
-- 限制返回数量
SELECT * FROM employees LIMIT 5;
-- 分页查询(每页5条,第1页)
SELECT * FROM employees LIMIT 0, 5;
-- 第2页
SELECT * FROM employees LIMIT 5, 5;
-- 第3页
SELECT * FROM employees LIMIT 10, 5;
-- 使用OFFSET关键字
SELECT * FROM employees LIMIT 5 OFFSET 0;
-- 分页公式
-- LIMIT (page - 1) * pageSize, pageSize
-- 例如:第3页,每页10条
-- LIMIT (3-1)*10, 10 = LIMIT 20, 10
-- 分页排序
SELECT * FROM employees
ORDER BY salary DESC
LIMIT 0, 5; -- 工资最高的5人聚合函数
基本聚合函数
sql
-- COUNT:计数
SELECT COUNT(*) AS 总人数 FROM employees;
SELECT COUNT(department) AS 有部门的人数 FROM employees;
SELECT COUNT(DISTINCT department) AS 部门数量 FROM employees;
-- SUM:求和
SELECT SUM(salary) AS 工资总和 FROM employees;
-- AVG:平均值
SELECT AVG(salary) AS 平均工资 FROM employees;
-- MAX:最大值
SELECT MAX(salary) AS 最高工资 FROM employees;
-- MIN:最小值
SELECT MIN(salary) AS 最低工资 FROM employees;
-- 组合使用
SELECT
COUNT(*) AS 总人数,
SUM(salary) AS 工资总和,
AVG(salary) AS 平均工资,
MAX(salary) AS 最高工资,
MIN(salary) AS 最低工资
FROM employees;GROUP BY分组
sql
-- 按部门分组统计
SELECT
department,
COUNT(*) AS 人数,
AVG(salary) AS 平均工资,
SUM(salary) AS 工资总和
FROM employees
GROUP BY department;
-- 多列分组
SELECT
department,
position,
COUNT(*) AS 人数,
AVG(salary) AS 平均工资
FROM employees
GROUP BY department, position;
-- GROUP BY与ORDER BY结合
SELECT
department,
COUNT(*) AS 人数
FROM employees
GROUP BY department
ORDER BY 人数 DESC;
-- GROUP BY与LIMIT结合
SELECT
department,
AVG(salary) AS 平均工资
FROM employees
GROUP BY department
ORDER BY 平均工资 DESC
LIMIT 3;HAVING子句
sql
/*
* WHERE vs HAVING:
* WHERE:过滤行,在分组前执行
* HAVING:过滤组,在分组后执行
*/
-- 查询平均工资大于15000的部门
SELECT
department,
AVG(salary) AS 平均工资
FROM employees
GROUP BY department
HAVING AVG(salary) > 15000;
-- 查询人数大于2的部门
SELECT
department,
COUNT(*) AS 人数
FROM employees
GROUP BY department
HAVING COUNT(*) > 2;
-- WHERE和HAVING结合
SELECT
department,
COUNT(*) AS 人数,
AVG(salary) AS 平均工资
FROM employees
WHERE status = 'active' -- 先过滤状态
GROUP BY department
HAVING AVG(salary) > 15000; -- 再过滤分组
-- HAVING中使用别名
SELECT
department,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING avg_salary > 15000;高级查询技巧
CASE表达式
sql
-- 简单CASE
SELECT
name,
salary,
CASE
WHEN salary >= 30000 THEN '高薪'
WHEN salary >= 20000 THEN '中薪'
WHEN salary >= 10000 THEN '普通'
ELSE '低薪'
END AS 薪资等级
FROM employees;
-- 统计各薪资等级人数
SELECT
CASE
WHEN salary >= 30000 THEN '高薪'
WHEN salary >= 20000 THEN '中薪'
ELSE '普通'
END AS 薪资等级,
COUNT(*) AS 人数
FROM employees
GROUP BY
CASE
WHEN salary >= 30000 THEN '高薪'
WHEN salary >= 20000 THEN '中薪'
ELSE '普通'
END;
-- 在ORDER BY中使用CASE
SELECT * FROM employees
ORDER BY
CASE department
WHEN '技术部' THEN 1
WHEN '销售部' THEN 2
ELSE 3
END,
salary DESC;子查询
sql
-- 标量子查询(返回单个值)
SELECT * FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
-- 列子查询(返回一列)
SELECT * FROM employees
WHERE department IN (
SELECT DISTINCT department FROM employees WHERE salary > 20000
);
-- 行子查询(返回一行)
SELECT * FROM employees
WHERE (department, salary) = (
SELECT department, MAX(salary)
FROM employees
GROUP BY department
LIMIT 1
);
-- EXISTS子查询
SELECT * FROM employees e1
WHERE EXISTS (
SELECT 1 FROM employees e2
WHERE e2.department = e1.department
AND e2.salary > e1.salary
);
-- FROM子句中的子查询
SELECT
department,
avg_salary
FROM (
SELECT
department,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department
) AS dept_avg
WHERE avg_salary > 15000;UNION操作
sql
-- UNION:合并结果集,去重
SELECT name, department FROM employees WHERE department = '技术部'
UNION
SELECT name, department FROM employees WHERE salary > 20000;
-- UNION ALL:合并结果集,不去重
SELECT name, department FROM employees WHERE department = '技术部'
UNION ALL
SELECT name, department FROM employees WHERE salary > 20000;
-- INTERSECT(MySQL 8.0+):交集
SELECT name FROM employees WHERE department = '技术部'
INTERSECT
SELECT name FROM employees WHERE salary > 20000;
-- EXCEPT(MySQL 8.0+):差集
SELECT name FROM employees WHERE department = '技术部'
EXCEPT
SELECT name FROM employees WHERE salary < 20000;本章小结
本章学习了:
- 基本查询:SELECT、DISTINCT、别名
- 条件查询:WHERE、比较运算符、逻辑运算符
- 模糊查询:LIKE通配符
- 排序:ORDER BY、自定义排序
- 分页:LIMIT、OFFSET
- 聚合函数:COUNT、SUM、AVG、MAX、MIN
- 分组:GROUP BY、HAVING
- 高级技巧:CASE、子查询、UNION
下一章,我们将学习多表查询,了解如何进行表连接操作。
