我用 SQL server 2005 测试了这段代码,感觉还可以。希望它可以帮助一些人。
WITH tItems
AS
(
SELECT A.ItemId, A.ItemValue, (SELECT COALESCE(SUM(B.ItemValue), 0)
FROM Items B
WHERE B.ItemId < A.ItemId) AS PrevItemTotal,
(SELECT COALESCE(SUM(C.ItemValue), 0)
FROM Items C
WHERE C.ItemId <= A.ItemId) AS CurrItemTotal
FROM Items A
),
tPayments
AS
(
SELECT A.PaymentId, A.PaymentValue, (SELECT COALESCE(SUM(B.PaymentValue), 0)
FROM Payments B
WHERE B.PaymentId < A.PaymentId) AS PrevPaymentTotal,
(SELECT COALESCE(SUM(C.PaymentValue), 0)
FROM Payments C
WHERE C.PaymentId <= A.PaymentId) AS CurrPaymentTotal
FROM Payments A
),
tDistribution
AS
(
SELECT *,
CASE
WHEN PrevPaymentTotal - PrevItemTotal <= 0 THEN
CASE
WHEN PaymentValue - (PrevItemTotal-PrevPaymentTotal) <= ItemValue THEN PaymentValue - (PrevItemTotal-PrevPaymentTotal)
ELSE ItemValue
END
ELSE -- PrevPaymentTotal - PrevItemTotal > 0
CASE
WHEN ItemValue - (PrevPaymentTotal - PrevItemTotal) < PaymentValue THEN ItemValue - (PrevPaymentTotal - PrevItemTotal)
ELSE PaymentValue
END
END AS Distribution
FROM tItems X, tPayments Y
WHERE Y.CurrPaymentTotal > X.PrevItemTotal AND Y.PrevPaymentTotal < X.CurrItemTotal
)
SELECT ItemId, ItemValue, PaymentId, PaymentValue, Distribution,
ItemValue - SUM (Distribution) OVER (PARTITION BY ItemId) AS Remaining
FROM tDistribution