我有一个价格为4欧元的产品,我需要为3个部门分配这笔钱。在第二列上,我需要获取该产品的行数,并为部门数量划分。

我的查询:

select
   department, totalvalue,
   (totalvalue / (select count(*) from departments d2 where d2.department = p.product))
       dividedvalue
from products p, departments d
where d.department = p.department

Department  Total Value  Divided Value
----------  -----------  -------------
A           4            1.3333333
B           4            1.3333333
C           4            1.3333333

但是,当我总结值时,我会得到3,999999。当然,有数百行我会得到很大的差异...是否有机会定义2个小数数和最后一个值? (我的结果是1.33 1.33 1.34)我的意思是,某种方法可以调整最后一行?

有帮助吗?

解决方案

有六个精度的小数,如果您将最终数字围绕两个小数,则需要大约5,000件交易才能注意到一分钱。将小数的数量增加到可接受的水平将消除大多数问题,即使用9个小数,您需要大约5,000,000件交易才能注意到一分钱。

其他提示

为了处理此问题,对于每一行,您必须执行以下操作:

  • 执行分区
  • 将结果舍入到适当数量的美分
  • 总结圆金数量和分区操作结果之间的差异
  • 当差异之和超过最低小数位时(在这种情况下为0.01),将该数量添加到下一个分区操作的结果(舍入后)。

这将在整行上均匀分配分数。不幸的是,没有简单的方法在SQL中使用简单的查询来执行此操作。最好在程序代码中执行此操作。

至于它的重要性,当涉及金融应用程序和机构时,即使只有一分钱,即使只能发生每一个x纪录,也很重要。通常,用户希望看到价值与一分钱(或您的单位货币单位)保持联系。

最重要的是,您不想允许像 “超人III” 或者 “办公空间” 发生。

也许您可以制作总计的第四行 - 总和(a,b,c)。但这取决于您想做什么,如果您需要确切的价值,则可以保持分数,否则,不关心虚拟损失

也可以简单地将特定值的舍入差异添加到要舍入的下一个数字(在舍入之前)。这样,桩始终保持相同的大小。

这是由TSQL(Microsoft SQL Server)实现的 马丁:

-- Set parameters.
DECLARE @departments INTEGER = 3;
DECLARE @totalvalue DECIMAL(19, 7) = 4.0;

WITH
CTE1 AS
(
    -- Create the data upon which to perform the calculation.
    SELECT

        1 AS Department
        , @totalvalue AS [Total Value]
        , CAST(@totalvalue / @departments AS DECIMAL(19, 7)) AS [Divided Value]
        , CAST(ROUND(@totalvalue / @departments, 2) AS DECIMAL(19, 7)) AS [Rounded Value]

    UNION ALL

    SELECT

        CTE1.Department + 1
        , CTE1.[Total Value]
        , CTE1.[Divided Value]
        , CTE1.[Rounded Value]

    FROM

        CTE1

    WHERE

        Department < @departments
),

CTE2 AS
(
    -- Perform the calculation for each row.
    SELECT

        Department
        , [Total Value]
        , [Divided Value]
        , [Rounded Value]
        , CAST([Divided Value] - [Rounded Value] AS DECIMAL(19, 7)) AS [Rounding Difference]
        , [Rounded Value] AS [Calculated Value]

    FROM

        CTE1

    WHERE

        Department = 1

    UNION ALL

    SELECT

        CTE1.Department
        , CTE1.[Total Value]
        , CTE1.[Divided Value]
        , CTE1.[Rounded Value]
        , CAST(CTE1.[Divided Value] + CTE2.[Rounding Difference] - ROUND(CTE1.[Divided Value] + CTE2.[Rounding Difference], 2) AS DECIMAL(19, 7))
        , CAST(ROUND(CTE1.[Divided Value] + CTE2.[Rounding Difference], 2) AS DECIMAL(19, 7))

    FROM

        CTE2

            INNER JOIN CTE1
                ON CTE1.Department = CTE2.Department + 1

)

-- Display the results with totals.
SELECT 

    Department
    , [Total Value]
    , [Divided Value]
    , [Rounded Value]
    , [Rounding Difference]
    , [Calculated Value]

FROM 

    CTE2

UNION ALL

SELECT

    NULL
    , NULL
    , SUM([Divided Value])
    , SUM([Rounded Value])
    , NULL
    , SUM([Calculated Value])

FROM

    CTE2

;

输出:

enter image description here

您可以插入顶部想要的任何数字。我不确定该算法是否有数学证明。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top