内容简介:本文主要介绍MySQL相关知识,包括安装、配置、优化等内容。风哥教程参考MySQL官方文档MySQL SQL Syntax、MySQL Server Administration。 01 更多视频教程www.fgedu.net.cn 02 学习交流加群风哥微信: itpux-com
Part01-基础概念与理论知识
复杂查询是指使用高级SQL技术来解决复杂的数据查询问题,包括子查询、连接查询、聚合函数、窗口函数等。这些技术可以帮助我们从数据库中获取更复杂、更有价值的信息。 03 学习交流加群风哥QQ113257174
Part02-生产环境规划与建议
2.1 标量子查询
-- 标量子查询:返回单个值
SELECT
name,
salary,
(SELECT AVG(salary) FROM employees) AS avg_salary
FROM employees;
-- 标量子查询作为条件
SELECT * FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
2.2 列子查询
-- 列子查询:返回一列值
SELECT * FROM employees
WHERE department_id IN (SELECT id FROM departments WHERE name LIKE '%技术%');
2.3 行子查询
-- 行子查询:返回一行值
SELECT * FROM employees
WHERE (department_id, salary) IN (SELECT department_id, MAX(salary) FROM employees GROUP BY department_id);
2.4 表子查询
-- 表子查询:返回一个表
SELECT * FROM (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS dept_avg
WHERE avg_salary > 8000;
2.5 相关子查询
-- 相关子查询:子查询依赖外部查询
SELECT e1.name, e1.salary, e1.department_id
FROM employees e1
WHERE e1.salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.department_id = e1.department_id);
Part03-生产环境项目实施方案
3.1 内连接
-- 内连接:只返回匹配的行
SELECT e.name, e.salary, d.name AS department
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;
3.2 左连接
-- 左连接:返回左表所有行,右表匹配的行
SELECT e.name, e.salary, d.name AS department
FROM employees e
LEFT JOIN departments d ON e.department_id = d.id;
3.3 右连接
-- 右连接:返回右表所有行,左表匹配的行
SELECT e.name, e.salary, d.name AS department
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.id;
3.4 全连接
-- 全连接:返回两个表的所有行(MySQL不直接支持,使用UNION)
SELECT e.name, e.salary, d.name AS department
FROM employees e
LEFT JOIN departments d ON e.department_id = d.id
UNION
SELECT e.name, e.salary, d.name AS department
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.id
WHERE e.id IS NULL;
3.5 自连接
-- 自连接:表与自身连接
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.id;
3.6 多表连接
-- 多表连接:连接多个表
SELECT e.name, e.salary, d.name AS department, p.name AS project
FROM employees e
JOIN departments d ON e.department_id = d.id
JOIN employee_project ep ON e.id = ep.employee_id
JOIN projects p ON ep.project_id = p.id;
Part04-生产案例与实战讲解
4.1 基本聚合函数
-- 基本聚合函数
SELECT
COUNT(*) AS total_employees,
SUM(salary) AS total_salary,
AVG(salary) AS avg_salary,
MAX(salary) AS max_salary,
MIN(salary) AS min_salary
FROM employees;
4.2 分组聚合
-- 分组聚合
SELECT
department_id,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
4.3 带条件的聚合
-- 带条件的聚合
SELECT
department_id,
COUNT(*) AS total_employees,
COUNT(CASE WHEN salary > 10000 THEN 1 END) AS high_salary_count,
AVG(CASE WHEN age > 30 THEN salary END) AS avg_salary_over_30
FROM employees
GROUP BY department_id;
4.4 嵌套聚合
-- 嵌套聚合
SELECT
MAX(avg_salary) AS max_avg_salary
FROM (
SELECT
department_id,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS dept_avg;
Part05-风哥经验总结与分享
5.1 排名函数
-- 排名函数
SELECT
name,
department_id,
salary,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num
FROM employees;
5.2 聚合窗口函数
-- 聚合窗口函数
SELECT
name,
department_id,
salary,
SUM(salary) OVER (PARTITION BY department_id) AS dept_total,
AVG(salary) OVER (PARTITION BY department_id) AS dept_avg,
COUNT(*) OVER (PARTITION BY department_id) AS dept_count
FROM employees;
5.3 移动窗口函数
-- 移动窗口函数
SELECT
date,
fgsales,
AVG(fgsales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg,
SUM(fgsales) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_sum
FROM fgsales_data;
5.4 窗口函数的高级用法
-- 窗口函数的高级用法
SELECT
name,
department_id,
salary,
FIRST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary DESC) AS highest_salary,
LAST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS lowest_salary,
LEAD(salary) OVER (PARTITION BY department_id ORDER BY salary DESC) AS next_higher_salary,
LAG(salary) OVER (PARTITION BY department_id ORDER BY salary DESC) AS previous_higher_salary
FROM employees;
6. 递归查询技巧
6.1 递归CTE基本用法
-- 递归CTE基本用法
WITH RECURSIVE cte AS (
-- 锚点查询
SELECT id, name, parent_id FROM categories WHERE parent_id IS NULL
UNION ALL
-- 递归查询
SELECT c.id, c.name, c.parent_id
FROM categories c
JOIN cte ON c.parent_id = cte.id
)
SELECT * FROM cte;
6.2 递归CTE生成序列
-- 递归CTE生成序列
WITH RECURSIVE numbers AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 10
)
SELECT * FROM numbers;
6.3 递归CTE计算层级
-- 递归CTE计算层级
WITH RECURSIVE category_hierarchy AS (
SELECT id, name, parent_id, 1 AS level FROM categories WHERE parent_id IS NULL
UNION ALL
SELECT c.id, c.name, c.parent_id, ch.level + 1
FROM categories c
JOIN category_hierarchy ch ON c.parent_id = ch.id
)
SELECT * FROM category_hierarchy ORDER BY level, id;
7. 复杂条件查询技巧
7.1 高级WHERE条件
-- 高级WHERE条件
SELECT * FROM employees
WHERE
(department_id = 1 AND salary > 10000) OR
(department_id = 2 AND salary > 8000) OR
(department_id IN (3, 4) AND salary > 6000);
7.2 使用CASE语句
-- 使用CASE语句
SELECT
name,
salary,
CASE
WHEN salary > 15000 THEN '高收入'
WHEN salary > 10000 THEN '中等收入'
ELSE '低收入'
END AS income_level
FROM employees;
7.3 使用IF函数
-- 使用IF函数
SELECT
name,
salary,
IF(salary > 10000, '高收入', '普通收入') AS income_level
FROM employees;
7.4 使用NULL处理函数
-- 使用NULL处理函数
SELECT
name,
COALESCE(manager_id, 0) AS manager_id,
IFNULL(commission, 0) AS commission,
NULLIF(salary, 0) AS non_zero_salary
FROM employees;
8. 性能优化技巧
8.1 使用索引
-- 确保WHERE条件和JOIN条件使用索引
CREATE INDEX idx_department_salary ON employees(department_id, salary);
8.2 避免SELECT *
-- 只查询需要的列
SELECT id, name, salary FROM employees WHERE department_id = 1;
8.3 使用EXPLAIN分析执行计划
-- 分析执行计划
EXPLAIN SELECT * FROM employees WHERE department_id = 1 AND salary > 10000;
8.4 优化子查询
-- 优化子查询:使用JOIN代替子查询
SELECT e.*
FROM employees e
JOIN (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS dept_avg ON e.department_id = dept_avg.department_id
WHERE e.salary > dept_avg.avg_salary;
8.5 使用LIMIT限制结果集
-- 使用LIMIT限制结果集
SELECT * FROM employees ORDER BY salary DESC LIMIT 10;
9. 实际案例分析
9.1 案例1:销售数据分析
-- 销售数据分析
SELECT
p.name AS product,
c.name AS category,
SUM(s.quantity) AS total_quantity,
SUM(s.quantity * p.price) AS total_fgsales,
AVG(s.quantity * p.price) AS avg_sale,
MAX(s.quantity * p.price) AS max_sale
FROM fgsales s
JOIN products p ON s.product_id = p.id
JOIN categories c ON p.category_id = c.id
WHERE s.sale_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY p.id, c.id
ORDER BY total_fgsales DESC
LIMIT 10;
9.2 案例2:员工绩效分析
-- 员工绩效分析
SELECT
e.name AS employee,
d.name AS department,
COUNT(s.id) AS sale_count,
SUM(s.quantity * p.price) AS total_fgsales,
RANK() OVER (PARTITION BY e.department_id ORDER BY SUM(s.quantity * p.price) DESC) AS dept_rank,
RANK() OVER (ORDER BY SUM(s.quantity * p.price) DESC) AS overall_rank
FROM employees e
LEFT JOIN fgsales s ON e.id = s.employee_id
LEFT JOIN products p ON s.product_id = p.id
JOIN departments d ON e.department_id = d.id
WHERE s.sale_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY e.id, d.id
ORDER BY total_fgsales DESC;
9.3 案例3:库存管理
-- 库存管理
SELECT
p.id AS product_id,
p.name AS product_name,
c.name AS category,
p.stock_quantity AS current_stock,
AVG(s.quantity) AS avg_daily_fgsales,
p.stock_quantity / AVG(s.quantity) AS days_of_inventory
FROM products p
LEFT JOIN fgsales s ON p.id = s.product_id AND s.sale_date BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW()
JOIN categories c ON p.category_id = c.id
GROUP BY p.id, c.id
HAVING days_of_inventory < 7
ORDER BY days_of_inventory ASC;
10. 总结
复杂查询是MySQL数据库操作的高级技术,掌握这些技巧可以帮助我们更有效地从数据库中获取有价值的信息。本文详细介绍了MySQL中的复杂查询技巧,包括子查询、连接查询、聚合函数、窗口函数、递归查询等。 04 风哥提示:
在使用复杂查询时,需要注意以下几点: 05更多学习教程公众号风哥教程itpux_com
- 选择合适的查询方法,根据具体场景选择最有效的查询方式
- 注意查询性能,避免使用过于复杂的查询影响数据库性能
- 使用索引来提高查询速度
- 使用EXPLAIN分析执行计划,优化查询语句
- 遵循最佳实践,写出高效、易维护的SQL语句
通过掌握这些复杂查询技巧,可以更有效地处理各种数据查询需求,提高数据分析能力和数据库操作效率。 06 from mysql视频:www.itpux.com
GF-MySQL数据库培训文档系列
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
