在函数调用后合并返回错误值然后乘法

Coalesce returning wrong value after a function call followed by multiplication

我有一份提供信息的报告,但我得到的信息不一致,原因是 SQL 视图或视图中嵌套的 SQL 函数似乎存在问题。我已经尝试找到一种调试 SQL 视图的方法,但是,SSMS 似乎只会调试存储过程,所以我不太确定如何逐步执行并查看发生了什么。这真的让我难住了,我忍不住想知道这是否是一个舍入问题。 GetItemAverageCost RETURNS DECIMAL(12,2) 和 sitli.QuantityIssuedAtStockUOM 中的数据类型是 System.Int64 / bigint(旁注:我很困惑为什么 LINQPad 为该列显示 2 种数据类型。在左侧的树中,展开 sitli 后table 并将鼠标悬停在 QuantityIssuedAtStockUOM 上,气球 BigInt NOT NULL 会弹出,但是当我 Take(100) 并将鼠标悬停在结果集中的列上时,它会显示 System.Int64)。不管怎样,这是 COALESCE 函数。

COALESCE((dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor, 0),1),0) -- 259.73 --ROUND(COALESCE((dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor, 0),1),0),2) -- 259.73 --COALESCE(ROUND((dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor,2), 0),1),0) -- 259.70 --COALESCE((ROUND(dbo.GetItemAverageCost(ItemModel.IDItemModel),2)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor, 0),1),0) -- 259.73

原创/错误合并:

COALESCE(dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM,0)

我不确定还包括什么,但我没有在网上找到很多资源来深入了解这种情况。非常感谢您的宝贵时间。

编辑:GetItemAverageCost:

    ALTER FUNCTION GetItemAverageCost
        (
            @IDItemModel varchar(8000)
        )

        RETURNS DECIMAL(16,4)
        --RETURNS DECIMAL(12,2)
        AS
        BEGIN
        RETURN
        (
        SELECT 
            COALESCE(AVG(poli.UnitPrice),0) as AvgCost
--          COALESCE(ROUND(AVG(poli.UnitPrice),0),2) as AvgCost 260.00
        FROM ItemModel im
        LEFT JOIN VendorItem vi
            ON im.IDItemModel = vi.IDItemModel
        JOIN POLineItem poli
            ON vi.IDVendorItem = poli.IDVendorItem

        WHERE
            im.IDItemModel = @IDItemModel

        GROUP BY
            im.IDItemModel,
            im.ItemNumber
        )
        END

修复;让你的函数 return 16,4 而不是 12,2 然后在乘以数量后舍入两位两位小数。

"When a given report is run, there are no errors thrown. But the calculations are off. For example a part number 12 shows a quantity of 24 were issued at a cost of 9.73. However, each part costs .82 so the calculation should be 9.68. I'm not sure where the difference of 5 cents is coming from. The 9.73 is the result of the COALESCE function above. Hopefully this makes sense"

运行 SQL 仅适用于独立于函数的第 12 部分,您会看到平均值为 10.822083333333333333333333333333(10.82 5/24ths)

  • 24*单价 = 259.73 美元
  • 单价 = 259.73/24
  • 单价 = 10.82 美元 5/24。

您会看到差异为 $.05

  • 10.82 5/24。 *24 = 259.73
  • 10.82 * 24 = 259.68

5 美分的差异并没有平均分配到剩余的 24 美分中。因此在使用您的函数时出现舍入误差。

当你想到去商店买东西时,它总是等于一分钱。当你去加油站时,他们会收取最接近的 .00001 美分。 (或者在你的情况下是 4 位小数)

直到乘以数量或实际现金需要易手时,才进行四舍五入。如果做得太早,你会看到你看到的舍入错误。

因此,您消除了 over/under 收费舍入错误,最多您会比您应该少收或多收一分钱。

好的,非常感谢一路上提供帮助的所有人。有几个问题阻止我得到正确的答案。一方面,我大部分时间都在使用不正确的表达方式。其次,在我弄清楚要使用哪个表达式之后,接下来就是将 ROUND 函数放在正确的位置。

所以,我应该用来计算平均成本的表达式是:

COALESCE(dbo.GetItemAverageCost(Item.IDItemModel) / ISNULL(NULLIF(UOMFactor, 0),1),0)

当我将其移至 WorkOrderItemInstructionPartCosts 视图时,我的报告产生了 10.82 美元。然后我将 *sitli.QuantityIssuedAtStockUOM 添加到行中,得到 259.73 美元。然后我将 ROUND 函数应用于 COALESCE 函数,瞧!正在生成正确的值 ($259.68)。

最后一行看起来像这样:

ROUND(COALESCE(dbo.GetItemAverageCost(ItemModel.IDItemModel) / ISNULL(NULLIF(UOMFactor, 0),1),0),2)*sitli.QuantityIssuedAtStockUOM

再次感谢所有帮助我解决此问题的人,对于没有准确的信息一开始感到抱歉。 最好, 乔纳森