一文分享10个常用的MySQL高级用法

 更新时间:2025年12月17日 08:20:16   作者:刘大华  
MySQL 有很多高级但实用的功能,能让你的查询变得更简洁、更高效,今天分享 10 个我在工作中经常使用的 SQL 技巧,不用死记硬背,掌握了就能立刻提升你的数据库操作水平

MySQL 有很多高级但实用的功能,能让你的查询变得更简洁、更高效。

今天分享 10 个我在工作中经常使用的 SQL 技巧,不用死记硬背,掌握了就能立刻提升你的数据库操作水平!

1. CTE(WITH子句)——让复杂查询变清晰

-- 传统子查询,难以阅读
SELECT nickname 
FROM system_users 
WHERE dept_id IN (
    SELECT id FROM system_dept WHERE `name` = 'IT部'
);

-- 使用CTE,逻辑清晰
WITH ny_depts AS (
    SELECT id FROM system_dept WHERE `name` = 'IT部'
)
SELECT u.nickname
FROM system_users u
JOIN ny_depts nd ON u.dept_id = nd.id;

解释:

  • WITH ny_depts AS (...):先创建一个临时结果集,叫 ny_depts,里面只包含“IT部”的部门名称。
  • SELECT u.nickname FROM system_users u JOIN ny_depts...:再从用户表中找出那些部门ID在ny_depts里的员工昵称。

好处:把找部门和找人分成两步,逻辑更清楚,比嵌套子查询好读多了。

2. 窗口函数 —— 不分组也能统计

SELECT 
    name,
    department,
    salary,
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_in_dept,
    AVG(salary) OVER (PARTITION BY department) AS avg_salary
FROM employees;

解释:

  • PARTITION BY department:按部门“分组”,但不合并行,每行仍然保留。
  • RANK() OVER (...):在每个部门内部,按薪水从高到低排名(相同薪水并列)。
  • AVG(salary) OVER (...):计算每个部门的平均工资,并显示在每一行里。

对比 GROUP BYGROUP BY 会把多行合并成一行,而窗口函数保留原始行,同时加上统计值。

3. 条件聚合 —— 一行查出多个统计

SELECT 
    YEAR(created_at) AS year,
    COUNT(*) AS total,
    COUNT(CASE WHEN status = 'completed' THEN 1 END) AS completed,
    SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END) AS revenue
FROM orders
GROUP BY YEAR(created_at);

解释:

  • YEAR(created_at):提取订单年份。
  • COUNT(*):该年总订单数。
  • COUNT(CASE WHEN status = 'completed' THEN 1 END): 如果状态是 'completed',就返回 1,否则返回 NULL
  • COUNT() 只统计非 NULL 值,所以这行就是“完成的订单数”。
  • SUM(CASE WHEN ... THEN amount ELSE 0 END):只对完成的订单求金额总和。

关键:不用写多个子查询,一条语句搞定全年报表!

4. 自连接 —— 同一张表自己连自己

SELECT e1.name, e2.name
FROM employees e1
JOIN employees e2 
  ON e1.department = e2.department
  AND e1.id < e2.id  
  AND ABS(e1.salary - e2.salary) <= e1.salary * 0.1;

解释:

  • employees e1 JOIN employees e2:把员工表当成两个副本(e1 和 e2)来连接。
  • e1.department = e2.department:只找同一个部门的人。
  • e1.id < e2.id:避免重复配对(比如 Alice-Bob 和 Bob-Alice 只保留一个)。
  • ABS(...):计算两人薪水差是否 ≤ 10%。

用途:找“相似记录”“配对关系”“上下级”等场景非常有用。

5.EXISTS替代IN—— 更高效的存在判断

SELECT name FROM customers c
WHERE EXISTS (
    SELECT 1 FROM orders o 
    WHERE o.customer_id = c.id AND o.amount > 1000
);

解释:

  • 对每一位客户 c,检查是否存在一笔订单满足:
    • 订单的 customer_id 等于这个客户的 id
    • 订单金额 > 1000
  • SELECT 1:这里不需要返回具体字段,只要知道“有没有”就行,所以用 1 最轻量。
  • 为什么快?:一旦找到一条匹配订单,就立刻停止搜索,不像 IN 可能要加载全部订单 ID。

注意:如果子查询可能返回 NULLIN 会失效(因为 x IN (..., NULL) 永远为 UNKNOWN),而 EXISTS 不受影响。

6. JSON 函数 —— 轻松读取 JSON 字段

SELECT 
    name,
    profile->>'$.address.city' AS city,
    JSON_EXTRACT(profile, '$.age') AS age
FROM users
WHERE profile->>'$.city' = 'Beijing';

解释:

  • profile 是一个 JSON 类型字段,比如:{"address": {"city": "Beijing"}, "age": 30}
  • profile->>'$.address.city'
    • ->> 是简写,等价于 JSON_UNQUOTE(JSON_EXTRACT(...))
    • 返回字符串 "Beijing"(去掉引号)
  • JSON_EXTRACT(profile, '$.age'):返回 30(带类型,可能是数字)
  • WHERE profile->>'$.city' = 'Beijing':筛选城市是北京的用户。

适用场景:用户偏好、动态表单、日志等结构不固定的字段。

7. 生成列 —— 数据库自动帮你算

CREATE TABLE products (
    id INT PRIMARY KEY,
    width DECIMAL(10,2),
    height DECIMAL(10,2),
    area DECIMAL(10,2) AS (width * height) STORED
);

INSERT INTO products (id, width, height) VALUES (1, 5, 10);

解释:

  • area DECIMAL(...) AS (width * height) STORED
    • 这是一个“存储型生成列”,数据库会自动计算 width * height 并存下来。
    • 如果不加 STORED,就是“虚拟列”(每次查询时计算,不占存储)。
  • 插入时只需给 widthheightarea 自动变成 50

优势:避免应用层重复计算,还能给 area 加索引加速查询!

8. 多表更新 —— 一条语句更新关联数据

UPDATE customers c
JOIN (
    SELECT customer_id, SUM(amount) AS total
    FROM orders
    GROUP BY customer_id
) o ON c.id = o.customer_id
SET c.total_spent = o.total;

解释:

  • 子查询 o:先按客户 ID 统计每个人的总消费。
  • UPDATE customers c JOIN o ...:把客户表和统计结果连接起来。
  • SET c.total_spent = o.total:直接把统计值写回客户表。

好处:不用在程序里循环“查一个、改一个”,减少网络开销,保证原子性。

9.GROUP_CONCAT—— 多行变一行

SELECT 
    department,
    GROUP_CONCAT(name ORDER BY salary DESC SEPARATOR ', ') AS members
FROM employees
GROUP BY department;

解释:

  • GROUP BY department:按部门分组。
  • GROUP_CONCAT(name ...):把每个部门的所有员工名字拼成一个字符串。
  • ORDER BY salary DESC:按薪水从高到低排序后再拼接。
  • SEPARATOR ', ':用逗号加空格分隔名字。

典型用途:导出名单、展示标签、汇总明细等。

默认最多拼 1024 字符,可通过 SET SESSION group_concat_max_len = 1000000; 调大。

10.INSERT ... ON DUPLICATE KEY UPDATE—— 智能插入/更新

INSERT INTO page_views (page_url, view_date, view_count)
VALUES ('/home', CURDATE(), 1)
ON DUPLICATE KEY UPDATE 
    view_count = view_count + 1;

解释:

  • 尝试插入一条新记录:页面 /home,今天日期,访问次数为 1。
  • 如果因为唯一索引冲突(比如 (page_url, view_date) 是唯一键)导致插入失败:
    • 就执行 ON DUPLICATE KEY UPDATE 部分
    • 把原有的 view_count 加 1
  • 效果:第一次访问创建记录,之后每次访问自动 +1,完美实现计数器!

前提:表必须有主键或唯一索引,否则不会触发更新。

到此这篇关于一文分享10个常用的MySQL高级用法的文章就介绍到这了,更多相关MySQL高级用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL系列之十一 日志记录

    MySQL系列之十一 日志记录

    这篇文章主要介绍了MySQL日志文件详解,本文分别讲解了错误日志、二进制日志、通用查询日志、慢查询日志、Innodb的在线redo日志、更新日志等日志类型和作用介绍,需要的朋友可以参考下
    2021-07-07
  • 线上MYSQL同步报错故障处理方法总结(必看篇)

    线上MYSQL同步报错故障处理方法总结(必看篇)

    下面小编就为大家带来一篇线上MYSQL同步报错故障处理方法总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • MySQL基本表查询操作汇总之单表查询+多表操作大全

    MySQL基本表查询操作汇总之单表查询+多表操作大全

    本文全面介绍了MySQL单表查询与多表操作的关键技术,包括基本语法、高级查询、表别名使用、多表连接及子查询等,并提供了丰富的实例,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • MySQL8.0 索引优化invisible index详情

    MySQL8.0 索引优化invisible index详情

    这篇文章主要介绍了MySQL8.0 索引优化invisible index详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • MySQL 撤销日志与重做日志(Undo Log与Redo Log)相关总结

    MySQL 撤销日志与重做日志(Undo Log与Redo Log)相关总结

    这篇文章主要介绍了MySQL 撤销日志与重做日志(Undo Log与Redo Log)相关总结,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下
    2021-03-03
  • 搞定mysql行转列的7种方法以及列转行

    搞定mysql行转列的7种方法以及列转行

    在MySQL数据库中,有时候我们需要将一列数据转化为行数据,以便更好地进行数据分析和处理,下面这篇文章主要给大家介绍了关于搞定mysql行转列的7种方法以及列转行的相关资料,需要的朋友可以参考下
    2024-03-03
  • MySQL连接被阻塞的问题分析与解决方案(从错误到修复)

    MySQL连接被阻塞的问题分析与解决方案(从错误到修复)

    在Java应用开发中,数据库连接是必不可少的一环,然而,在使用MySQL时,我们可能会遇到MySQL服务器由于检测到过多的连接失败,自动阻止了来自该主机的连接请求,本文将深入分析该问题的原因,并提供完整的解决方案,需要的朋友可以参考下
    2025-04-04
  • mysql中json基础查询详解(附图文)

    mysql中json基础查询详解(附图文)

    MySQL提供了一些函数来对JSON数据进行操作,下面这篇文章主要给大家介绍了关于mysql中json基础查询的相关资料,文中通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • 详解Mysql主从同步配置实战

    详解Mysql主从同步配置实战

    这篇文章主要介绍了详解Mysql主从同步实战,实例分析了Mysql主从同步的原理和实现,非常具有实用价值,需要的朋友可以参考下。
    2017-03-03
  • mysql 常用命令集锦(Linux/Windows)

    mysql 常用命令集锦(Linux/Windows)

    这篇文章主要介绍了Linux/Windows系统下mysql 常用的命令,需要的朋友可以参考下
    2014-07-07

最新评论