sql - 为什么 SQL Server 不使用 SUM 遵循 BODMAS 数学规则?
问题描述
昨天我遇到了一个遗留存储过程的非常令人困惑的问题,虽然我已经“修复”了它,但我觉得我不明白为什么需要它。
BODMAS - 数学运算的顺序:
括号,顺序,除法,乘法,加法,减法
因此,加法发生在减法之前。从技术上讲,它们的权重相同并且“同时”发生,因为它们通常相互抵消。
同意这一点后,我们应该能够同意以下都是正确的:
- 1000 - (300 + 300) = 400
- 1000 - 300 + 300 = 400
- (1000 - 300) + 300 = 1000
但是,SQL 将中间的计算为 1000。我可以通过添加括号轻松解决这个问题。我担心的是,虽然这个示例简洁明了,但当数字 300 来自 Coalesced Sums 时,已经有很多括号飞来飞去。它们完全有可能被遵循 BODMAS 逻辑的人意外删除,或者在代码优化器中被标记为冗余。
这里有一些代码可以自己尝试
CREATE TABLE #TempData ([Number] INT)
INSERT INTO #TempData VALUES(200)
INSERT INTO #TempData VALUES(100)
SELECT 1000 - (SUM(Number) + SUM(Number))
FROM #TempData
SELECT 1000 - SUM(Number) + SUM(Number)
FROM #TempData
SELECT (1000 - SUM(Number)) + SUM(Number)
FROM #TempData
DROP TABLE #TempData
解决方案
1000 - 300 + 300 = 400
这是错误的。
正如您所说,+
并且-
权重相同并且同时发生。按照惯例,基本运算都是左结合的,所以一行中多个相同权重的算子是从左到右处理的:
1000 - 300 + 300 = ((1000 - 300) + 300
这在任何地方都是正确的(数学、SQL、大多数编程语言),所以问题不是 SQL 和传统数学符号之间的区别,而是对约定的误解。
推荐阅读
- python - Python:将(0...无穷大)范围内的值标准化为(0...1)。当输入是唯一的时,数据框中所有行的输出都是相同的
- c++ - 从 base64string 转换为 json wuth jsoncons
- python - 节点请求与 python 会话
- reactjs - 在 React JSX 中克隆字典
- java - Serializable ThreadLocal 是如何实现的?
- android - 如何处理片段回栈
- angular - 在角度路由中混合组件和模块
- c# - 关闭应用程序时从 BackgroudDownloader 更新进度
- azure-devops - 从 pipeline.yaml 中的服务连接导出 ARM_CLIENT_ID 和 ARM_CLIENT_SECRET
- java - 强制杀死,停止或销毁java中的线程