我有一张包含位置,ID,费用类型和费用的表格。 有三种特定的费用类型需要分配给其他费用。
示例数据SQL Fiddle
在示例数据中,为简单起见,仅显示一个位置。
三种类型值x
,y
,z
是要分布在其他类型(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
类型。在此示例中,a
为aDiff
,因为有两个-1.74
值,ID 101将为10.5 +(aDiff / 2),从而导致a
具有审核值9.63
任何人都知道如何解决这个问题?我正在努力从哪里开始使用sql脚本来做到这一点。
编辑: 使用最新代码更新了SQL小提琴。我发现的问题是在将其应用于完整数据集时,值是不正确的。原始数据的A-Z之和应该等于新数据中A-E的总和,但它并不是。不知道现阶段发生了什么。
答案 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]