在同一位置的记录上分配$ value

时间:2015-08-26 02:43:35

标签: sql-server tsql math

我有一张包含位置,ID,费用类型和费用的表格。 有三种特定的费用类型需要分配给其他费用。

示例数据SQL Fiddle

在示例数据中,为简单起见,仅显示一个位置。

三种类型值xyz是要分布在其他类型(a->e)上的类型。

分发需要分为三个阶段,一个针对三种类型中的每一种,并且有一个审计跟踪,显示类型x到每个类型的数量,然后是y和{{ 1}}。订单为z

分布基于每个类型的分组总和,因此在示例数据中,分组是

x -> y ->z

a - 31.3 b - 15 c - 68.4 d - 57.3 e - 55.3 的值为x分配公式为 -12.7

然后将

aDiff = (a*(x / (a+b+c+d+e)))均匀地拆分为每个aDiff类型。在此示例中,aaDiff,因为有两个-1.74值,ID 101将为10.5 +(aDiff / 2),从而导致a具有审核值9.63

任何人都知道如何解决这个问题?我正在努力从哪里开始使用sql脚本来做到这一点。

编辑: 使用最新代码更新了SQL小提琴。我发现的问题是在将其应用于完整数据集时,值是不正确的。原始数据的A-Z之和应该等于新数据中A-E的总和,但它并不是。不知道现阶段发生了什么。

1 个答案:

答案 0 :(得分:0)

解决这个问题的最简单方法是1)创建一个函数来执行内部计算,2)使用左自连接中的函数。您在问题中发布的一些值与SQL Fiddle中的值不同,因此我使用了小提琴中的值。

另外,我们不清楚你应该如何计算你的审计值,因为9.63 + -.874 = 8.756而不是10.5,所以我把这个计算表示为(aDiff / 2)。

我希望这会有所帮助。

--Step1: Create a function that calculates the xDiff distribution formula, aDiff =  (a*(x / (a+b+c+d+e)))

IF OBJECT_ID('aDiff_fn','fn') IS NOT NULL
DROP FUNCTION aDiff_fn
GO

CREATE FUNCTION [dbo].[aDiff_fn] (@a decimal(10,6))
RETURNS decimal(10,6)
AS
BEGIN

RETURN

@a *
(
    (SELECT sum(cost)
    FROM expenses
    WHERE [type] = 'x')
/

    (SELECT sum(cost)
    FROM expenses
    WHERE [type] in ('a','b','c','d','e'))
)
END
GO

---Step2: Compare original values and the aggregates using a self JOIN

SELECT
    e.Location,
    e.ID, 
    e.[Type],
    e.Cost,
    g.CountOfType,
    g.TotalCostOfType,
    g.aDiff,
    e.Cost+(g.aDiff/g.CountOfType) AS yValue,
    (g.aDiff/g.CountOfType) AS AuditValue
FROM
    expenses AS e
LEFT JOIN
    (
    SELECT
        [type],
        count([type]) AS CountOfType,
        sum(cost) AS TotalCostOfType,
        dbo.aDiff_fn(sum(cost)) AS aDiff
    FROM
        expenses
    GROUP BY
        [type]
    ) AS g
    ON e.[type] = g.[type]