【问题标题】:SQL division giving wrong answer [duplicate]SQL部门给出错误答案[重复]
【发布时间】:2023-03-14 22:52:01
【问题描述】:

可能重复:
What is wrong with this SQL Server query division calculation?

我在 SQL 中划分两个值,例如

SELECT SUM(totalCalls), 
    SUM(EnteredBTN), 
    SUM(EnteredBTN) * 100 / SUM(totalCalls),
    SUM(EnteredACC), 
    SUM(EnteredACC) / SUM(totalCalls), 
    SUM(SentToTrans),
    SUM(SentToTrans) * 100 / SUM(totalCalls),
    SUM(Complete_Information), 
    SUM(Complete_Information) * 100 / SUM(SentToTrans) 

现在当我执行 SUM(EnteredACC)/SUM(totalCalls)7/48 时,它应该给我 .14 但它却给了我 0。 p>

当我执行 SUM(EnteredACC)*100/SUM(totalCalls) 时,它应该给出 14.58(或四舍五入时为 15),但结果却是 14。有人可以帮忙吗?

【问题讨论】:

  • 您将整数除以整数。这导致一个整数。如果您想要十进制结果,请尝试*100.0*1.0。如果您想指定小数位数,请使用 Lamak 和 Void Ray 的答案等显式转换 - 但请指定显式精度 + 比例。

标签: sql sql-server sum divide


【解决方案1】:

答案很简单,很可能EnteredACCtotalCalls 列的数据类型是INT(或SMALLINTBIGINT 等),因此您的结果是INT。因此,14.58 变为 14,0.14 变为 0。您需要对数据类型进行强制转换(隐式或显式):

SUM(CAST(EnteredACC AS DECIMAL(16,4))/SUM(totalCalls)

【讨论】:

  • 谢谢,除了这个特殊的临时表之外,我已将所有内容都设置为十进制类型。我以某种方式错过了它,感谢您的帮助。
【解决方案2】:

你需要浮点除法,而不是整数除法。

SELECT SUM(totalCalls), 
    SUM(EnteredBTN), 
    SUM(EnteredBTN)*100/CAST(SUM(totalCalls) as FLOAT),
    SUM(EnteredACC), 
    SUM(EnteredACC)/SUM(totalCalls), 
    SUM(SentToTrans),
    SUM(SentToTrans) * 100 / SUM(totalCalls),
    SUM(Complete_Information), 
    SUM(Complete_Information) * 100 / CAST(SUM(SentToTrans) as FLOAT)

【讨论】:

  • 我不同意 FLOAT 是正确的答案。
  • 出于好奇,为什么decimal更合适?
  • 因为 OP 似乎只需要两位小数。为什么 FLOAT 会更好,除了您最终会看到更大的数字(例如 14.58000000000000000001)?
  • 啊,明白了。所以这不是性能问题,而是风格问题?我只有大约一年的 SQL 经验,所以我不知道。谢谢。
  • 嗯,还有准确性。如果您特别想要它的近似属性,您应该只使用 FLOAT,恕我直言。在大多数业务应用程序(我永远不会说all)中,FLOAT 是没有保证的。我从 6.5 开始就一直在使用 SQL Server,但我还没有直接处理任何 FLOAT 是更好选择的客户系统。我确信它们存在,但是当我们谈论除以整数和表示百分比时,FLOAT 不是正确的选择。再次,恕我直言。
【解决方案3】:

试试:select cast(cast(7 as decimal(18,2))/cast(48 as decimal(18,2)) as decimal(18,2))

【讨论】:

  • 如果要显式转换为十进制,则应包括精度和小数位数。你知道默认值是什么吗?有OP吗?未来的读者会吗?
  • 我只是想指出问题出在数据类型上。精度和规模在这里不是问题。
  • 这仍然是一种糟糕的做法——尤其是在演示代码时——排除精度/比例/长度。这是我关于 VARCHAR 的论点,但它们同样适用于 DECIMAL、VARBINARY、DATETIME2 等:sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/…
  • Aaron,我不得不同意:Varchar,但对于十进制,特别是对于一些演示代码,默认值就可以了;恕我直言。
  • 你没有理解我的意思。没关系,希望其他读者能明白。
猜你喜欢
  • 2013-03-01
  • 2023-04-11
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-19
  • 2020-02-16
  • 1970-01-01
相关资源
最近更新 更多