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;  

六、性能优化关键技巧

  1. 索引使用原则

    • WHERE/JOIN条件字段建索引
    • 避免在索引列上使用函数(如YEAR(create_time)
    • 联合索引遵循最左前缀原则
  2. EXPLAIN分析执行计划

EXPLAIN SELECT * FROM orders WHERE status = 'SHIPPED';  

关注关键指标:

  • type:ALL(全表扫描)→ index/range(优化)
  • rows:预估扫描行数
  • Extra:Using filesort/Using temporary 需优化
  1. 避免性能陷阱
    • 大表分页用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更新统计信息,优化查询计划准确性。

正文到此结束
评论插件初始化中...
Loading...