SQL运算符优先级疑问:为何两条薪资查询语句结果不一致?
Why does the second SQL query return no records while the first works as expected?
这个问题的核心是整数除法的隐式类型转换在搞鬼!绝大多数SQL数据库(比如MySQL、SQL Server、PostgreSQL等)在处理两个整数的除法运算时,会默认返回整数结果,直接丢弃小数部分,而不是自动转为浮点数。
咱们拆解两条语句的执行过程就能明白差异:
第一条语句的执行逻辑
select first_name, last_name, salary from employee where salary < 200000 * 1/10
因为乘法和除法是同级运算符,数据库会从左到右依次计算:
- 先算
200000 * 1,结果是整数200000 - 再算
200000 / 10,虽然是整数除法,但结果刚好是整数20000 - 最后执行比较
salary < 20000,这完全符合你预期的条件,所以能返回正确记录
第二条语句的执行逻辑
select first_name, last_name, salary from employee where salary < 1/10 * 200000
同样按左到右顺序计算:
- 先算
1/10,两个操作数都是整数,数据库执行整数除法,结果直接取商的整数部分——也就是0(小数部分被丢弃了) - 再算
0 * 200000,结果自然是0 - 最后比较
salary < 0,显然你的员工薪资不可能小于0,所以没有记录返回
哪怕你给表达式加了括号 ((1/10) * 200000),也改变不了先执行 1/10 得到0的结果,最终还是和原语句一样的逻辑。
怎么解决这个问题?
只需要把其中一个操作数改成浮点数,强制数据库做浮点除法就行,比如:
-- 把1改成1.0,触发浮点运算 select first_name, last_name, salary from employee where salary < 1.0/10 * 200000
或者:
-- 把10改成10.0也可以 select first_name, last_name, salary from employee where salary < 1/10.0 * 200000
这样 1.0/10 会得到 0.1,再乘以200000就是 20000,和第一条语句的条件完全一致,就能返回你预期的结果了。
验证差异的小技巧
你可以单独运行这两个表达式,直接看结果结果差异:
SELECT 200000 * 1/10 AS result1, 1/10 * 200000 AS result2;
执行后会看到 result1 是 20000,result2 是 0,一下子就能直观理解问题所在啦!
内容的提问来源于stack exchange,提问作者Rahul Raj
相关产品推荐
相关产品推荐

