MsSQL FLOOR CEILING问题?或者有解释吗?

时间:2017-08-31 15:38:59

标签: sql sql-server

任何人都可以在MsSQL中尝试这个:

select floor(4.7000000000000000000000000000000000000)+0.5

我得到这个结果:5(!!)但应该是4.5!?

或者再试一次:

select floor(4.70 * 0.25000 * 0.2440 * 5.6325 * 3.0542 * 2.345 * 2.35 * 3.253 )+0.5

结果是89 !!但应该是:88.5?!

这是一个问题吗?或者有解释吗? (与CEILING相同的问题)

谢谢大家!

1 个答案:

答案 0 :(得分:2)

根据FLOOR的文档:

  

-- Syntax for SQL Server, Azure SQL Data Warehouse, Parallel Data Warehouse

     

FLOOR ( numeric_expression )

     

返回类型

     

返回与numeric_expression相同的类型。

问题在于它不是真的。它保留了基本类型,但如果是decimal类型,则比例缩小为0:

SELECT
    SQL_VARIANT_PROPERTY(4.00, 'precision') AS [precision]
    SQL_VARIANT_PROPERTY(4.00, 'scale') AS scale,

结果:精度3,比例2.

SELECT 
    SQL_VARIANT_PROPERTY(FLOOR(4.00), 'precision') AS [precision],
    SQL_VARIANT_PROPERTY(FLOOR(4.00), 'scale') AS scale

结果:精度3,比例0.一旦decimal达到最大精度,这就成了问题:

SELECT
    SQL_VARIANT_PROPERTY(4.7000000000000000000000000000000000000, 'precision') AS [precision]
    SQL_VARIANT_PROPERTY(4.7000000000000000000000000000000000000, 'scale') AS scale,

精度38,比例37.但FLOOR将其转换为精度38,比例0和

SELECT CONVERT(DECIMAL(38, 0), 4) + 0.5
根据{{​​3}},

结果为5:此结果应为decimal(40, 1),但由于超出了最大精度,因此缩放比例以保留尽可能多的数字在期间的前面,再次给我们decimal(38, 0)5

相反,这没有问题:

SELECT 4.0000000000000000000000000000000000000 + 0.5

结果是DECIMAL(38, 37),可以完全保留4.5000000000000000000000000000000000000

道德:要注意FLOOR(和CEILING)的这种消除尺度的方面,并在必要时降低精度,以免因溢出而缩小比例:

SELECT CONVERT(DECIMAL(3, 0),  FLOOR(4.70 * 0.25000 * 0.2440 * 5.6325 * 3.0542 * 2.345 * 2.35 * 3.253)) + 0.5

收益率88.5