我认为你可以在没有循环的情况下做到这一点,但你是否愿意是另一个问题。我认为有效的查询如下(SQL Fiddle here)。关键思想如下:
每个 SubtractAmount 的最终效果是减去 SubtractAmount 除以同一 PersonID 的所有后续 DivideAmount 的乘积。与 PersonID 关联的日期与此调整无关(幸运的是)。CTE AdjustedAdjustments 包含这些调整后的 SubtractAmount 值。
PersonID 的初始值除以该人员日期当天或之后的所有 DivideAmount 值的乘积。
如果 x 的所有值都是正数,则 EXP(SUM(LOG(x))) 用作聚合产品。您应该限制 DivideAmount 值以确保这一点,或相应地调整代码。
如果没有 DivideAmounts,则关联产品为 NULL 并更改为 1。类似地,调整后的 SubtractAmount 值的 NULL 总和更改为零。左连接用于保留不受任何调整的值。
SQL Server 2012 支持聚合的 OVER 子句,这有助于聚合“所有以后的 DivideAmounts”。
WITH AdjustedAdjustments AS (
select
PersonID,
Date,
SubtractAmount/
EXP(
SUM(LOG(COALESCE(DivideAmount,1)))
OVER (
PARTITION BY PersonID
ORDER BY Date
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
)
) AS AdjustedSubtract,
DivideAmount
FROM TblAdj
)
SELECT
p.PersonID,
p.Value/COALESCE(EXP(SUM(LOG(COALESCE(DivideAmount,1)))),1)
-COALESCE(SUM(a.AdjustedSubtract),0) AS AmountAdjusted
FROM TblVal AS p
LEFT OUTER JOIN AdjustedAdjustments AS a
ON a.PersonID = p.PersonID
AND a.Date >= p.Date
GROUP BY p.PersonID, p.Value, p.Date;