MySQL 中的自定义变量用法、场景与最容易踩的坑

 更新时间:2026年01月22日 09:30:11   作者:sg_knight  
MySQL自定义变量是一种灵活的机制,可以用于临时存储和计算,但容易被误用,本文介绍了自定义变量的基本用法、典型使用场景以及容易踩的坑,建议在复杂SQL中谨慎使用,并推荐使用窗口函数、子查询等替代方案,感兴趣的朋友跟随小编一起看看吧

在 MySQL 中,**自定义变量(User-Defined Variables)**是一种非常“灵活”的机制。
它不需要提前声明,可以在 SQL 中直接赋值、直接使用,因此在写复杂 SQL、做临时计算时经常能看到它的身影。

但同时,它也是 MySQL 里最容易被误用的特性之一。

本文从实际使用角度,系统讲清楚:
它是什么、怎么用、适合干什么、不适合干什么。

一、什么是 MySQL 自定义变量

MySQL 自定义变量是指以 @ 开头的变量,例如:

@count
@total_price
@row_num

它的核心特征有三点:

  1. 无需声明,直接使用
  2. 作用域是当前会话(session)
  3. 主要用于 SQL 执行过程中的临时存储

只要当前连接不断开,这个变量就一直存在。

二、自定义变量的基本用法

1. 变量赋值

常见的赋值方式有两种。

方式一:使用 SET

SET @a = 10;
SET @b := 20;

方式二:在 SELECT 中赋值

SELECT @a := 10;

=:= 在赋值场景下都能用,但在复杂 SQL 中,推荐使用 :=,可读性更好,也更安全。

2. 使用变量

变量赋值后,可以直接使用:

SELECT @a + @b;

也可以在查询中混合使用:

SELECT
  id,
  price,
  @total := @total + price AS running_total
FROM orders,
     (SELECT @total := 0) t;

三、自定义变量的典型使用场景

1. 计算累计值(运行总和)

这是最经典的用法之一:

SELECT
  id,
  amount,
  @sum := @sum + amount AS total_amount
FROM payments,
     (SELECT @sum := 0) s;

用于报表、统计、导出数据时非常方便。

2. 模拟行号(MySQL 8 之前)

在 MySQL 8.0 之前,没有 ROW_NUMBER(),很多人用自定义变量模拟:

SELECT
  @rownum := @rownum + 1 AS row_num,
  name
FROM users,
     (SELECT @rownum := 0) r;

3. 复杂条件的中间状态保存

例如在一条 SQL 中保存上一次的值:

SELECT
  id,
  score,
  @prev := score AS prev_score
FROM scores
ORDER BY id;

四、自定义变量最容易踩的坑

这是重点

1. 执行顺序不保证

MySQL 不保证 SELECT 中表达式的计算顺序

例如:

SELECT @a := @a + 1, @a FROM table;

不能假设左边一定先执行。

官方文档明确说明:
不要依赖用户变量在同一 SELECT 中的计算顺序

2. 在 WHERE / ORDER BY 中使用不安全

SELECT *
FROM users
WHERE score > (@avg := @avg + 1);

这种写法极不可靠,不同执行计划可能结果不同。

3. 并发场景下容易被误解

自定义变量是 会话级别 的,不是全局的。

  • 不同连接之间 互不影响
  • 但同一个连接里,多条 SQL 会共用

很多新手会误以为它是“全局变量”,这是错的。

4. 可读性和可维护性差

复杂 SQL 中大量使用 @变量

  • 后期几乎无法维护
  • 新人很难理解
  • 调试成本极高

五、什么时候不该用自定义变量

以下场景,强烈不推荐

  1. 业务核心逻辑
  2. 更新、删除等写操作依赖变量顺序
  3. 高并发、强一致性要求
  4. 可以用窗口函数、子查询、CTE 解决的场景(MySQL 8+)

六、替代方案建议

如果你使用的是 MySQL 8.0+,优先考虑:

  • ROW_NUMBER()
  • SUM() OVER (...)
  • LAG / LEAD
  • CTE(WITH 语句)

这些都是语义清晰、结果可控的正规方案。

七、总结一句话

MySQL 自定义变量是“应急工具”,不是“长期方案”。

  • 写报表、一次性 SQL:可以用
  • 写核心业务、长期维护代码:尽量别用

如果你发现一条 SQL 里出现了 5 个以上的 @变量
那大概率说明:设计该重构了。

到此这篇关于MySQL 中的自定义变量详解(用法、场景与坑)的文章就介绍到这了,更多相关mysql自定义变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Win10下mysql 8.0.15 安装配置方法图文教程

    Win10下mysql 8.0.15 安装配置方法图文教程

    这篇文章主要为大家详细介绍了Win10下mysql 8.0.15 安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • MySQL中Update、select联用操作单表、多表,及视图与临时表的区别

    MySQL中Update、select联用操作单表、多表,及视图与临时表的区别

    本篇文章给大家分享了MySQL中Update、select联用操作单表、多表,及视图与临时表的区别,有兴趣的朋友学习下吧。
    2018-06-06
  • Mysql根据一个表的数据更新另一个表数据的SQL写法(三种写法)

    Mysql根据一个表的数据更新另一个表数据的SQL写法(三种写法)

    这篇文章主要介绍了Mysql根据一个表的数据更新另一个表数据的SQL写法,本文给大家分享三种解决方法,需要的朋友可以参考下
    2023-06-06
  • Mysql联表查询索引失效的几种问题解决

    Mysql联表查询索引失效的几种问题解决

    本文主要介绍了Mysql联表查询索引失效的几种问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-10-10
  • MySQL中外键的创建、约束以及删除

    MySQL中外键的创建、约束以及删除

    这篇文章主要给大家介绍了关于MySQL中外键的创建、约束以及删除的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • MySQL中的RIGHT JOIN和CROSS JOIN操作示例

    MySQL中的RIGHT JOIN和CROSS JOIN操作示例

    本文详细介绍了MySQL中的RIGHT JOIN和CROSS JOIN操作,RIGHT JOIN返回右表中的所有记录及与左表中的记录相匹配的记录,而CROSS JOIN返回两个表中所有可能的组合,通过实际示例和输出结果,我们展示了如何使用RIGHT JOIN和CROSS JOIN进行数据库查询,一起看看吧
    2023-07-07
  • 关于MySQL的体系结构及存储引擎图解

    关于MySQL的体系结构及存储引擎图解

    这篇文章主要介绍了关于MySQL的体系结构及存储引擎图解,MySQL整体的逻辑结构可以分为4层,客户层、服务层、存储引擎层、数据层,需要的朋友可以参考下
    2023-05-05
  • mysql 5.7.17 安装配置方法图文教程

    mysql 5.7.17 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 5.7.17 安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • mysql修改自增主键数值无效的问题及解决

    mysql修改自增主键数值无效的问题及解决

    这篇文章主要介绍了mysql修改自增主键数值无效的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • MySQL如何清空慢查询文件

    MySQL如何清空慢查询文件

    这篇文章主要介绍了MySQL如何清空慢查询文件,如何在线生成一个新的慢查询文件,感兴趣的小伙伴们可以参考一下
    2015-12-12

最新评论