実行中の合計が計算されたソース テーブルに適用される「期日」の境界を定義するヘルパー テーブルを使用して、各実行中の合計額と「期日」の境界との交点を計算できます。
With Receipt As ( --< Sample source table Select * From (Values ('R1', 100), ('R2', 100), ('R3', 70), ('R4', 50), ('R5', 200) ) V (ReceiptNo, Amount) ), ReceiptWithTotal As ( --< Source table with Running Totals calculated Select *, SUM(Amount) Over (Order By ReceiptNo Rows Unbounded Preceding) - Amount As RunningTotalBefore, SUM(Amount) Over (Order By ReceiptNo Rows Unbounded Preceding) As RunningTotalAfter From Receipt ), Due As ( --< Helper table to define intervals (can be generated dynamically to cover any Total) Select * From (Values ('D1', 0, 100), ('D2', 100, 200), ('D3', 200, 300), ('D4', 300, 400), ('D5', 400, 500), ('D6', 500, 600) ) V (DueNo, AmountLow, AmountHigh) ) Select DueNo, ReceiptNo, IIF(AmountHigh < RunningTotalAfter, AmountHigh, RunningTotalAfter) - IIF(AmountLow > RunningTotalBefore, AmountLow, RunningTotalBefore) As Amount From Due Inner Join ReceiptWithTotal On NOT (RunningTotalAfter <= AmountLow OR RunningTotalBefore >= AmountHigh)
プレ>注意:
SUM(...) Over (Order By ... Rows Unbounded Preceding)
およびIIF(...)
SQL Server 2012+ でのみ使用できます。サブクエリを使用して SQL Server 2008 でも同じことができますが、効率は大幅に低下します:With Receipt As ( --< Sample source table Select * From (Values ('R1', 100), ('R2', 100), ('R3', 70), ('R4', 50), ('R5', 200) ) V (ReceiptNo, Amount) ), ReceiptWithTotal As ( --< Source table with Running Totals calculated Select *, RunningTotalAfter - Amount As RunningTotalBefore From ( Select *, (Select SUM(Amount) From Receipt B Where B.ReceiptNo <= A.ReceiptNo) As RunningTotalAfter From Receipt A ) A ), Due As ( --< Helper table to define intervals (can be generated dynamically to cover any Total) Select * From (Values ('D1', 0, 100), ('D2', 100, 200), ('D3', 200, 300), ('D4', 300, 400), ('D5', 400, 500), ('D6', 500, 600) ) V (DueNo, AmountLow, AmountHigh) ) Select DueNo, ReceiptNo, CASE WHEN AmountHigh < RunningTotalAfter THEN AmountHigh ELSE RunningTotalAfter END - CASE WHEN AmountLow > RunningTotalBefore THEN AmountLow ELSE RunningTotalBefore END As Amount From Due Inner Join ReceiptWithTotal On NOT (RunningTotalAfter <= AmountLow OR RunningTotalBefore >= AmountHigh)
プレ>