ループなしでもできると思いますが、やりたいかどうかは別問題です。私がうまくいくと思うクエリは以下のとおりです(SQL Fiddleはこちら)。主なアイデアは次のとおりです。
各SubtractAmountには、SubtractAmountを、同じPersonIDの後続のすべてのDivideAmountの積で割った値を差し引くという最終的な効果があります。PersonIDに関連付けられている日付は、この調整には関係ありません(幸いなことに)。CTE AdjustedAdjustmentsには、これらの調整されたSubtractAmount値が含まれています。
PersonIDの初期値は、その人物の日付以降のすべてのDivideAmount値の積で除算されます。
EXP(SUM(LOG(x)))は、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;