程序员Alex
6/27/2025
救命啊!我在做一个简单的减法查询时遇到了 Error 1690,这问题简直要把我逼疯了 🤯
我的表结构是这样的:
-- 表结构大概长这样 STEP_ID BIGINT UNSIGNED NAME VARCHAR(255) -- 其他字段...
当我运行这个查询时:
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组合,感觉像是在玩排列组合游戏:
-- 尝试1:只转换STEP_ID SELECT `NAME`, 202000 - CAST(STEP_ID AS UNSIGNED) FROM my_table WHERE `Name` = 'aaa'; -- 尝试2:只转换202000 SELECT `NAME`, CAST(202000 AS UNSIGNED) - STEP_ID FROM my_table WHERE `Name` = 'aaa'; -- 尝试3:两个都转换 SELECT `NAME`, CAST(202000 AS UNSIGNED) - CAST(STEP_ID AS UNSIGNED) FROM my_table WHERE `Name` = 'aaa'; -- 尝试4:转换整个表达式 SELECT `NAME`, CAST((CAST(202000 AS UNSIGNED) - STEP_ID) AS UNSIGNED) FROM my_table WHERE `Name` = 'aaa'; -- 尝试5:终极组合拳 SELECT `NAME`, CAST((CAST(202000 AS UNSIGNED) - CAST(STEP_ID AS UNSIGNED)) AS UNSIGNED) FROM my_table WHERE `Name` = 'aaa';
因为这是生产环境的一个关键报表查询,老板下午就要看数据了!⏰
有没有人遇到过类似的问题啊?这到底是MySQL的bug还是我哪里理解错了?我已经在Google上搜了2小时了,还是没解决...
PS:顺便吐槽一下,MySQL的类型系统有时候真的让人想砸键盘!💢
技术控老刘
6/27/2025
嘿,朋友!👋 看到你的问题我完全感同身受 - MySQL这个BIGINT UNSIGNED的减法问题简直是个经典坑啊!我去年也被它折磨得够呛,当时差点把咖啡洒在键盘上 ☕💻
这其实是MySQL类型系统的一个"特性"(或者说坑😂)。当你在做无符号数减法时,如果结果可能是负数,MySQL就会直接报错而不是自动转换类型。这就像你告诉银行"我账户里永远不会有负数",然后取钱时系统就死板地拒绝任何可能导致负数的交易一样!
SELECT `NAME`, 202000 - CAST(STEP_ID AS SIGNED) AS result FROM my_table WHERE `Name` = 'aaa'; -- 把无符号转为有符号,MySQL就不会抱怨了 -- 这是最干净利落的解决方案
SELECT `NAME`, IF(202000 > STEP_ID, 202000 - STEP_ID, STEP_ID - 202000) AS result FROM my_table WHERE `Name` = 'aaa'; -- 加个判断确保不会出现负数 -- 适合需要绝对值的场景
ALTER TABLE my_table MODIFY STEP_ID BIGINT SIGNED; -- 如果业务允许,直接改成有符号类型 -- 一劳永逸,但需要评估影响
你一直在尝试各种UNSIGNED转换,但问题恰恰相反 - 我们需要的是允许负数结果!这就像试图用创可贴治疗骨折一样方向错了🩹
别灰心!这种问题真的很容易让人抓狂,特别是赶时间的时候。你现在已经知道怎么解决了,快去拯救你的报表吧!如果还有其他问题随时来问,我们这些被MySQL虐过的开发者要互相帮助嘛 😄
PS:下次遇到这种类型问题,记住MySQL的座右铭:"说不要负数,就真的不给负数!" 💪