MySQL查询语句全面指南
一、基础查询语句
MySQL中select的基本语法形式
sql
select 属性列表
from 表名和视图列表
[where 条件表达式]
[group by 属性名[having 条件表达式]]
[order by 属性名[asc|desc]]
[limit <offset>,row count]
说明:
where子句:按照"条件表达式"指定的条件进行查询。
group by子句:按照"属性名"指定的字段进行分组。
having子句:有group by才能having子句,只有满足"条件表达式"中指定的条件的才能够输出。group by子句通常和count()、sum()等聚合函数一起使用。
order by子句:按照"属性名"指定的字段进行排序。排序方式由"asc"和"desc"两个参数指出,默认是按照"asc"来排序,即升序。
1. SELECT基本查询
sql
查询所有列 SELECT * FROM employees;
查询特定列 SELECT first_name, last_name, salary FROM employees;
使用DISTINCT去重 SELECT DISTINCT department_id FROM employees;
2. WHERE条件查询
sql
基本条件 SELECT * FROM employees WHERE salary > 5000;
多条件组合 SELECT * FROM employees WHERE department_id = 10 AND salary > 6000;
使用BETWEEN范围查询 SELECT * FROM employees WHERE salary BETWEEN 4000 AND 8000;
二、高级查询功能
1. 聚合函数与GROUP BY
sql
常用聚合函数 SELECT COUNT(*) AS total_employees,
AVG(salary) AS avg_salary,
MAX(salary) AS max_salary,
MIN(salary) AS min_salary,
SUM(salary) AS total_salary FROM employees;
GROUP BY分组 SELECT department_id, COUNT(*) AS emp_count,
AVG(salary) FROM employees GROUP BY department_id;
2. HAVING子句
sql
筛选分组结果 SELECT department_id,
AVG(salary) AS avg_salary FROM employees
GROUP BY department_id HAVING AVG(salary) > 5000;
3. 多表连接查询
sql
内连接 SELECT e.first_name, e.last_name, d.department_name
FROM employees e INNER JOIN departments d ON e.department_id = d.department_id;
左外连接 SELECT e.first_name, e.last_name, d.department_name
FROM employees e LEFT JOIN departments d ON e.department_id = d.department_id;
自连接 SELECT e1.employee_id, e1.first_name, e2.first_name AS manager_name
FROM employees e1 LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;
三、子查询与复杂查询
1. 子查询
sql
WHERE子句中的子查询 SELECT first_name, last_name, salary
FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
FROM子句中的子查询 SELECT dept_avg.department_id, dept_avg.avg_salary
FROM ( SELECT department_id, AVG(salary) AS avg_salary FROM employees
GROUP BY department_id ) AS dept_avg WHERE dept_avg.avg_salary > 6000;
2. EXISTS/NOT EXISTS
sql
查找有下属的管理者
SELECT first_name, last_name
FROM employees e WHERE EXISTS ( SELECT 1 FROM employees
WHERE manager_id = e.employee_id );
3. 公用表表达式(CTE)
sql
-- 使用WITH子句创建
CTE WITH dept_stats AS
( SELECT department_id,
COUNT(*) AS emp_count,
AVG(salary) AS avg_salary FROM employees
GROUP BY department_id )
SELECT * FROM dept_stats
WHERE emp_count > 5 ORDER BY avg_salary DESC;
四、查询优化技巧
1. 索引使用最佳实践
sql
-- 创建合适索引
CREATE INDEX idx_emp_dept ON employees(department_id);
CREATE INDEX idx_emp_name ON employees(last_name, first_name);
-- 强制使用索引
SELECT * FROM employees FORCE INDEX(idx_emp_dept) WHERE department_id = 10;
2. EXPLAIN分析查询
sql
-- 分析查询执行计划
EXPLAIN SELECT e.first_name, d.department_name
FROM employees e JOIN departments d ON e.department_id = d.department_id
WHERE e.salary > 5000;
五、实用查询技巧
1. 条件逻辑
sql
-- CASE表达式
SELECT first_name, last_name, salary, CASE
WHEN salary < 5000 THEN '初级'
WHEN salary BETWEEN 5000 AND 10000 THEN '中级' ELSE '高级' END AS level FROM employees;
2. 窗口函数
sql
-- 排名函数
SELECT first_name, last_name, salary,
RANK() OVER (ORDER BY salary DESC) AS salary_rank,
DENSE_RANK() OVER (ORDER BY salary DESC) AS salary_dense_rank,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num FROM employees;
-- 分区窗口函数
SELECT department_id, first_name, last_name, salary,
AVG(salary) OVER (PARTITION BY department_id) AS dept_avg_salary FROM employees;
3. JSON处理
sql
-- JSON数据查询
SELECT employee_id, JSON_EXTRACT(profile, '$.skills') AS skills,
JSON_CONTAINS(profile, '"MySQL"', '$.skills') AS has_mysql FROM employees_json;
-- 更新JSON字段
UPDATE employees_json SET profile = JSON_SET(profile, '$.skills[0]', 'PostgreSQL')
WHERE employee_id = 101;
六、高级连接技术
1. 交叉连接
sql
-- 生成笛卡尔积
SELECT e.first_name, d.department_name
FROM employees e CROSS JOIN departments d;
2. 自然连接
sql
-- 自动匹配同名列
SELECT first_name, last_name, department_name
FROM employees NATURAL JOIN departments;
3. 使用USING简化连接
sql
-- 当连接列名相同时
SELECT e.first_name, d.department_name
FROM employees e JOIN departments d USING (department_id);
七、事务与锁定查询
1. 事务控制
sql
-- 事务示例
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- 或 ROLLBACK;
2. 锁定查询
sql
-- 锁定行
SELECT * FROM employees WHERE employee_id = 101 FOR UPDATE;
-- 共享锁
SELECT * FROM departments WHERE department_id = 5 LOCK IN SHARE MODE;
八、性能监控与调优
1. 查询性能分析
sql
-- 开启性能分析
SET profiling = 1;
-- 执行查询
SELECT * FROM employees WHERE salary > 5000;
-- 查看分析结果
SHOW PROFILE; SHOW PROFILES;
2. 索引使用情况
sql
-- 查看索引使用统计
SELECT * FROM sys.schema_index_statistics WHERE table_schema = 'your_database';
-- 查找未使用索引
SELECT * FROM sys.schema_unused_indexes;
九、特殊查询场景
1. 递归查询
sql
-- 递归CTE查询组织架构
WITH RECURSIVE org_hierarchy AS
(
-- 基础查询:顶级管理者
SELECT employee_id, first_name, last_name, manager_id, 1 AS level
FROM employees WHERE manager_id
IS NULL UNION ALL
-- 递归查询:下属员工
SELECT e.employee_id, e.first_name, e.last_name, e.manager_id, h.level + 1
FROM employees e JOIN org_hierarchy h ON e.manager_id = h.employee_id
)
SELECT * FROM org_hierarchy ORDER BY level, employee_id;
2. 全文搜索
sql
-- 创建全文索引
CREATE FULLTEXT INDEX idx_ft_content ON articles(content);
-- 全文搜索查询
SELECT * FROM articles WHERE MATCH(content)
AGAINST('MySQL performance' IN NATURAL LANGUAGE MODE);
十、MySQL 8.0新特性
1. 通用表表达式
sql
-- 多个
CTE WITH dept_stats AS
(
SELECT department_id, COUNT(*) AS emp_count FROM employees GROUP BY department_id
),
high_salary AS
( SELECT employee_id, salary FROM employees WHERE salary > 8000 )
SELECT d.department_id, d.emp_count, COUNT(h.employee_id) AS high_paid_count
FROM dept_stats d LEFT JOIN high_salary h ON h.employee_id
IN ( SELECT employee_id FROM employees WHERE department_id = d.department_id )
GROUP BY d.department_id, d.emp_count;
2. 窗口函数增强
sql
-- 计算移动平均
SELECT date, sales, AVG(sales)
OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
AS moving_avg FROM daily_sales;
以上内容涵盖了MySQL查询的各个方面,从基础查询到高级功能,再到性能优化和特殊场景处理。实际应用中,应根据具体需求和数据特点选择合适的查询方式,并通过EXPLAIN等工具不断优化查询性能。