CloudFog API Gateway

Limited Time

200+ AI Models Integration Hub

Claim Offer Now
Resolvedmysql

MySQL 诡异 Error 1690:BIGINT UNSIGNED 减法运算如何避免越界错误?😫

开发者David

8/28/2025

14 views3 likes

嘿各位MySQL大神!😅 我遇到了一个超级诡异的Error 1690问题,已经折腾了一下午了还是没搞定,求帮忙看看!

问题描述: 我在执行这个简单的减法查询时:

SELECT `NAME`, 202000 - STEP_ID FROM my_table WHERE `Name` = 'aaa';

居然报错:

Error Code: 1690
BIGINT UNSIGNED value is out of range in '(202000 - `my_db`.`my_table`.`STEP_ID`)'

最诡异的是!😤 如果我手动把STEP_ID的值写进去计算就完全没问题!但用字段名就会报错...

我的表结构:

  • STEP_ID是BIGINT UNSIGNED类型
  • 当前数据中STEP_ID的值是202001(所以202000-202001=-1)

我已经尝试了各种CAST组合(都快把CAST用烂了):

-- 尝试1:只转换STEP_ID SELECT `NAME`, 202000 - CAST(STEP_ID AS UNSIGNED) FROM... ❌失败 -- 尝试2:只转换常量 SELECT `NAME`, CAST(202000 AS UNSIGNED) - STEP_ID FROM... ❌失败 -- 尝试3:两边都转换 SELECT `NAME`, CAST(202000 AS UNSIGNED) - CAST(STEP_ID AS UNSIGNED) FROM... ❌还是失败! -- 甚至尝试嵌套CAST... SELECT `NAME`, CAST((CAST(202000 AS UNSIGNED) - STEP_ID) AS SIGNED) FROM... ❌依然不行

感觉MySQL对UNSIGNED的处理有点迷啊...明明手动计算没问题,用字段就不行 😫

项目deadline就在明天,这个查询又必须用,急死我了!有没有哪位遇到过类似问题的大佬指点一下?

PS:顺便吐槽下,MySQL的错误信息有时候真的不够友好啊...这个1690错误谁能一眼看出是UNSIGNED减法的问题嘛!🙄

更新:刚刚发现如果STEP_ID小于202000就没问题,所以确实是负数的问题...但怎么绕过呢?

1 Answers

程序员小李

8/28/2025

Best Answer9

Answer #1 - Best Answer

嘿,朋友!👋 我完全理解你现在的抓狂心情 - 这个BIGINT UNSIGNED的减法问题简直就像MySQL给我们开的一个恶意玩笑!😅 记得我第一次遇到这个Error 1690时,差点把键盘给砸了...

为什么会出现这个错误?

简单来说,MySQL的UNSIGNED类型就像"永远正能量"的乐观主义者 - 它拒绝接受任何负数结果!🤦‍♂️ 当你用202000减去更大的STEP_ID(202001)时,MySQL会固执地认为:"不行!UNSIGNED怎么能出现负数!" 即使你用了CAST,它还是会先检查原始运算。

解决方案大放送 💡

经过无数次踩坑,我发现这几个方法最管用:

方法1:使用SIGNED强制转换(最推荐)

SELECT `NAME`, 202000 - CAST(STEP_ID AS SIGNED) AS result -- 先把STEP_ID转为有符号数 FROM my_table WHERE `Name` = 'aaa';

方法2:终极安全模式(我的最爱)

SELECT `NAME`, IF(202000 < STEP_ID, -(STEP_ID - 202000), -- 如果是负数就手动反转 202000 - STEP_ID) AS result FROM my_table WHERE `Name` = 'aaa';

方法3:使用变量中转(适合复杂计算)

SET @base = 202000; SELECT `NAME`, @base - CAST(STEP_ID AS SIGNED) AS result FROM my_table WHERE `Name` = 'aaa';

个人血泪教训 💔

  1. 类型转换顺序很重要:MySQL会先检查运算本身是否合法,再考虑CAST。所以必须在运算前就转换好类型
  2. 注意性能影响:在百万级数据表上,这些转换可能会轻微影响性能
  3. 常见陷阱:很多人会忘记WHERE条件中的类型匹配,导致隐式转换

为什么你的CAST尝试失败了?

你之前的尝试就像是在火山口装空调 ❌ - 虽然看起来很努力,但没解决根本问题。MySQL会先检查原始表达式 202000 - STEP_ID 是否合法(此时STEP_ID还是UNSIGNED),等发现不合法就直接报错了,根本不会执行到你的CAST部分!

鼓励一下 ✨

别灰心!这个MySQL的UNSIGNED减法问题确实很反直觉。你现在遇到的坑,每个MySQL开发者都踩过(包括我!)。搞定这个之后,你对MySQL类型系统的理解会上一个大台阶!🚀

如果还有其他问题,随时喊我 - 咱们一起把这个deadline干掉!💪 (顺便说,你最后的更新显示你已经找到问题根源了,这debug思路很赞!)

P.S. 如果你经常要做这类计算,考虑在表设计时直接用BIGINT SIGNED,能省去很多麻烦。这是我从5个项目总结出的经验 😉

CloudFog API Gateway 🔥 New User Special

💥 New User Offer: Get $1 Credit for ¥0.5

Claim Offer Now