MySQL查询语句大全 - 从基础到高阶完整指南
MySQL 查询语句大全:从基础到高级实战指南
MySQL作为最流行的关系型数据库之一,其查询语句的灵活性和高效性直接影响数据处理效率。本文将系统梳理200+核心查询语法,覆盖基础查询、聚合分析、多表操作、窗口函数等场景,配合示例代码和性能优化建议,助你全面提升SQL技能。
一、基础查询语句
1. SELECT基础结构
-- 查询所有字段
SELECT * FROM employees;
-- 查询特定字段
SELECT id, name, salary FROM employees;
-- 使用别名(AS可省略)
SELECT name AS 员工姓名, salary*12 "年薪" FROM employees;
📌 提示:避免
SELECT *
,明确字段可减少网络传输和内存占用。
2. 条件过滤(WHERE)
-- 数值比较
SELECT * FROM products WHERE price > 100;
-- 字符串匹配(区分大小写)
SELECT * FROM users WHERE name = 'John';
-- 日期范围
SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
-- 多条件组合
SELECT * FROM logs
WHERE status = 'SUCCESS'
AND (duration > 5 OR error_code IS NOT NULL);
3. 结果排序与分页
-- 单字段排序
SELECT * FROM products ORDER BY price DESC;
-- 多字段排序(先按部门升序,再按薪资降序)
SELECT name, dept, salary FROM employees
ORDER BY dept ASC, salary DESC;
-- 分页查询(LIMIT offset, count)
SELECT * FROM orders LIMIT 20 OFFSET 40; -- 等价于 LIMIT 40,20
二、聚合分析与分组统计
1. 常用聚合函数
函数 | 作用 | 示例 |
---|---|---|
COUNT() | 计数 | SELECT COUNT(*) FROM users |
SUM() | 求和 | SELECT SUM(sales) FROM region |
AVG() | 平均值 | SELECT AVG(rating) FROM reviews |
MAX() | 最大值 | SELECT MAX(temperature) FROM sensors |
MIN() | 最小值 | SELECT MIN(age) FROM students |
GROUP_CONCAT() | 合并字符串 | SELECT dept, GROUP_CONCAT(name) FROM emp GROUP BY dept |
2. GROUP BY分组实战
-- 按部门统计平均薪资
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id;
-- 多字段分组(按部门和职位统计人数)
SELECT dept, job_title, COUNT(*) AS emp_count
FROM staff
GROUP BY dept, job_title;
3. HAVING过滤分组结果
-- 筛选平均薪资>8000的部门
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
HAVING avg_salary > 8000;
-- 结合WHERE使用(先过滤行,再分组)
SELECT dept, COUNT(*) AS count
FROM employees
WHERE hire_date > '2020-01-01'
GROUP BY dept
HAVING count > 10;
三、多表关联查询
1. 连接类型对比
连接类型 | 关键词 | 特点 |
---|---|---|
内连接 | INNER JOIN | 仅返回两表匹配的行 |
左外连接 | LEFT JOIN | 保留左表所有行+匹配的右表行 |
右外连接 | RIGHT JOIN | 保留右表所有行+匹配的左表行 |
全外连接 | FULL OUTER JOIN | MySQL需用UNION模拟 |
交叉连接 | CROSS JOIN | 笛卡尔积(慎用!) |
2. JOIN实战示例
-- 内连接:查询员工及其部门信息
SELECT e.name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id;
-- 左连接:列出所有员工(包括未分配部门的)
SELECT e.name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id;
-- 三表关联:订单+客户+产品
SELECT o.order_id, c.name, p.product_name
FROM orders o
JOIN customers c ON o.cust_id = c.id
JOIN products p ON o.product_id = p.id;
3. UNION联合查询
-- 合并两个查询结果(自动去重)
SELECT city FROM offices
UNION
SELECT city FROM warehouses;
-- 保留重复记录
SELECT name FROM current_employees
UNION ALL
SELECT name FROM former_employees;
四、子查询与嵌套查询
1. 子查询类型
-- WHERE子句中的子查询(标量子查询)
SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products);
-- FROM子句中的子查询(派生表)
SELECT dept, avg_salary
FROM (SELECT dept_id, AVG(salary) avg_salary
FROM employees GROUP BY dept_id) AS dept_stats;
-- EXISTS检测存在性
SELECT name FROM customers
WHERE EXISTS (SELECT 1 FROM orders WHERE orders.cust_id = customers.id);
2. 关联子查询
-- 查询比同职位平均薪资高的员工
SELECT name, job_title, salary
FROM employees e1
WHERE salary > (SELECT AVG(salary)
FROM employees e2
WHERE e2.job_title = e1.job_title);
五、高级函数与窗口函数(MySQL 8.0+)
1. 条件逻辑函数
-- CASE表达式
SELECT name, salary,
CASE
WHEN salary > 10000 THEN '高薪'
WHEN salary BETWEEN 5000 AND 10000 THEN '中薪'
ELSE '低薪'
END AS salary_level
FROM employees;
-- IFNULL处理空值
SELECT name, IFNULL(bonus, 0) AS bonus FROM payroll;
2. 窗口函数实战
-- 计算部门内薪资排名
SELECT name, dept, salary,
RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dept_rank
FROM employees;
-- 移动平均(最近3个月)
SELECT month, revenue,
AVG(revenue) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM sales;
六、性能优化关键技巧
-
索引使用原则
- WHERE/JOIN条件字段建索引
- 避免在索引列上使用函数(如
YEAR(create_time)
) - 联合索引遵循最左前缀原则
-
EXPLAIN分析执行计划
EXPLAIN SELECT * FROM orders WHERE status = 'SHIPPED';
关注关键指标:
type
:ALL(全表扫描)→ index/range(优化)rows
:预估扫描行数Extra
:Using filesort/Using temporary 需优化
- 避免性能陷阱
- 大表分页用
WHERE id > ? LIMIT n
替代LIMIT m,n
- 用
BETWEEN
替代多个OR
条件 - 减少
SELECT *
,只取必要字段
- 大表分页用
七、实战综合案例
需求:统计2023年各部门销售额Top3的员工
WITH sales_data AS (
SELECT
e.dept_id,
e.name,
SUM(o.amount) AS total_sales,
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY SUM(o.amount) DESC) AS sales_rank
FROM orders o
JOIN employees e ON o.emp_id = e.id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY e.dept_id, e.name
)
SELECT dept_id, name, total_sales
FROM sales_data
WHERE sales_rank <= 3;
附录:常用函数速查表
字符串函数
CONCAT('Hello', 'World') -- 拼接字符串
SUBSTRING('MySQL', 2, 3) -- 截取子串 → 'ySQ'
REPLACE('foo bar', 'foo', '') -- 替换 → ' bar'
LENGTH('text') -- 字符串长度
日期函数
NOW() -- 当前时间
DATE_ADD(NOW(), INTERVAL 7 DAY) -- 7天后
DATEDIFF('2024-12-31', NOW()) -- 剩余天数
DATE_FORMAT(NOW(), '%Y/%m/%d') -- 格式化 → '2024/06/15'
数学函数
ROUND(123.4567, 2) -- 四舍五入 → 123.46
CEIL(15.2) -- 向上取整 → 16
FLOOR(15.8) -- 向下取整 → 15
RAND() -- 随机数 [0,1)
💡 最佳实践:定期使用
ANALYZE TABLE table_name
更新统计信息,优化查询计划准确性。
正文到此结束
相关文章
热门推荐
评论插件初始化中...