开发者David
8/28/2025
嘿各位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的值写进去计算就完全没问题!但用字段名就会报错...
我的表结构:
我已经尝试了各种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就没问题,所以确实是负数的问题...但怎么绕过呢?
程序员小李
8/28/2025
嘿,朋友!👋 我完全理解你现在的抓狂心情 - 这个BIGINT UNSIGNED的减法问题简直就像MySQL给我们开的一个恶意玩笑!😅 记得我第一次遇到这个Error 1690时,差点把键盘给砸了...
简单来说,MySQL的UNSIGNED类型就像"永远正能量"的乐观主义者 - 它拒绝接受任何负数结果!🤦♂️ 当你用202000减去更大的STEP_ID(202001)时,MySQL会固执地认为:"不行!UNSIGNED怎么能出现负数!" 即使你用了CAST,它还是会先检查原始运算。
经过无数次踩坑,我发现这几个方法最管用:
SELECT `NAME`, 202000 - CAST(STEP_ID AS SIGNED) AS result -- 先把STEP_ID转为有符号数 FROM my_table WHERE `Name` = 'aaa';
SELECT `NAME`, IF(202000 < STEP_ID, -(STEP_ID - 202000), -- 如果是负数就手动反转 202000 - STEP_ID) AS result FROM my_table WHERE `Name` = 'aaa';
SET @base = 202000; SELECT `NAME`, @base - CAST(STEP_ID AS SIGNED) AS result FROM my_table WHERE `Name` = 'aaa';
你之前的尝试就像是在火山口装空调 ❌ - 虽然看起来很努力,但没解决根本问题。MySQL会先检查原始表达式 202000 - STEP_ID
是否合法(此时STEP_ID还是UNSIGNED),等发现不合法就直接报错了,根本不会执行到你的CAST部分!
别灰心!这个MySQL的UNSIGNED减法问题确实很反直觉。你现在遇到的坑,每个MySQL开发者都踩过(包括我!)。搞定这个之后,你对MySQL类型系统的理解会上一个大台阶!🚀
如果还有其他问题,随时喊我 - 咱们一起把这个deadline干掉!💪 (顺便说,你最后的更新显示你已经找到问题根源了,这debug思路很赞!)
P.S. 如果你经常要做这类计算,考虑在表设计时直接用BIGINT SIGNED,能省去很多麻烦。这是我从5个项目总结出的经验 😉