SQL小数点前1位

SQL 1 Digit Before The Decimal Place

我将总计的比率存储在 table 中,因此我知道我只会有 0 到 1 之间的值,小数点后 4 位就足够精确了。因此,我将 table 列创建为 DECIMAL(5,4).

在计算人口数据时,我发现了一个奇怪的行为,其中 SQL 似乎需要在小数点前多出 2 位,所以如果我使用 DECIMAL(5,4)DECIMAL(6,4) 我收到 Arithmetic overflow error converting int to data type numeric. 错误。我必须将它推到 DECIMAL(7,4) 作为分界线的一侧,然后将整个分界线包裹在另一个铸件中以获得我实际需要的精度。

SQL 将每个不同的精度视为不同的数据类型,调用转换,所以我意识到在大规模完成时会增加工作量,因为我无法直接转换为 DECIMAL(5,4) 我将其存储为。我也很好奇是什么原因导致的。

下面的例子说明了这个问题。它应该适用于 DECIMAL(2,1),但它只能适用于 DECIMAL(3,1)。即使那样,结果也保留到小数点后 6 位。任何人都可以至少解释一下这里发生的事情,并希望有一种避免这种情况而不加倍施法的方法吗?

DECLARE @SalesTable TABLE (ProductId INT, Size NVARCHAR(2), Quantity INT)
INSERT INTO @SalesTable VALUES (123, 'S', 5), (123, 'M', 20), (123, 'L', 15), (123, 'XL', 10)

SELECT Size, sales.Quantity / CAST(sales.Total AS DECIMAL(3,1)) AS SalesRatio
FROM (
    SELECT Size, Quantity, SUM([Quantity]) OVER (PARTITION BY ProductId) AS Total
    FROM @SalesTable
) AS sales

使用额外的小数并生成不同精度的结果

Size    SalesRatio
S       0.100000
M       0.400000
L       0.300000
XL      0.200000

我不是很理解你的困惑。在您的示例中,salesTotal1 的值为 50。这需要小数点左边两位。

可能混淆的是小数的内部类型。虽然乘法的规则很复杂,除法的规则非常非常神秘,但加法的规则要简单得多:类型不变。

因此,总数需要符合小数值。

如果你关心算术运算的结果的类型,那么转换整个表达式:

SELECT Size,
       CAST(sales.Quantity * 1.0 / sales.Total AS DECIMAL(3,1)) AS SalesRatio

* 1.0可能不是必需的,但它确保除法有小数位。

小数精度应设置为包含计算中包含的最大数字所需的最大长度(除非另有说明)。在本例中,Quantity 是数据类型 INT,其 min/max 从 -2^31 (-2,147,483,648) 到 2^31-1 (2,147,483,647)。要涵盖所有情况,您可以将数据类型设为 Decimal(16, 4)。任何整数的 12 位 + 小数点右边的 4 位。 SQL 如果您在商的分母上加上或乘以 1.0,服务器会自动扩展小数精度。像这样

DECLARE @SalesTable TABLE (ProductId INT, Size NVARCHAR(2), Quantity INT)
INSERT INTO @SalesTable VALUES (123, 'S', 5), (123, 'M', 20), (123, 'L', 15), (123, 'XL', 10)

SELECT Size, cast(sales.Quantity / (sales.Total*1.0) AS DECIMAL(16,4)) AS SalesRatio
FROM (
    SELECT Size, Quantity, SUM([Quantity]) OVER (PARTITION BY ProductId) AS Total
    FROM @SalesTable
) AS sales;

输出

Size    SalesRatio
S       0.1000
M       0.4000
L       0.3000
XL      0.2000