そうですね、Oracleを使用していると仮定します。これは、そのデータベースで最も簡単だからです。
必要なのは、支払額と比較した累積額です。したがって、支払いを最も早い請求書に適用したいとします。次のクエリはこれを行います。
select i.*,
(case when cumAmount <= p.payment then Amount
when cumAmount - i.Amount < p.payment then p.payment - (i.cumAmount - i.Amount)
else 0
end) as AppliedPayment
from (select p.InvoiceId, sum(p.payment) as payment
from Payment p
group by p.InvoiceId
) join
(select i.*,
sum(i.amount) over (partition by i.InvoiceId order by i.JobNum) as cumAmount
from Invoices i
) i
on p.InvoiceId = i.InvoiceId
したがって、請求書から金額の累積合計を作成するという考え方です。次に、これを支払いと比較します。累積額が支払い額より少ない場合は、請求額全体を適用できます。累積額が支払いよりもはるかに多い場合、何も適用できません。部分的な支払いがあるかもしれない境界条件があります。
最初のサブクエリは、重複を避けるために、請求書のすべての支払いを累積します。2番目のサブクエリは、累積請求額を計算します。
他の一部のデータベースは、累積合計を直接サポートしています(SQL Server2012)。その他の場合、この結果を得るには自己参加を行う必要があります。