【发布时间】:2017-03-30 15:02:16
【问题描述】:
我在一个表中同时包含费用和付款。付款被“应用”到费用中,以使账户余额为零。没有具体的应用顺序,只要所有费用都平衡为零(或大部分)。
在我尝试构建的 SP 之后,表格将有两种可能的状态。正如我所说,只要大多数费用的余额为零,我就不会关心它们是如何“应用”的。
CREATE TABLE dbo.Transactions (
TrxID INT IDENTITY,
TrxType BIT, -- 1 for Charges, 0 for Payments
TrxDescription VARCHAR(MAX),
Amount DECIMAL(13,2),
ApplyTo INT -- TrxID of the charge to which the payment is "applied"
);
INSERT INTO dbo.Transactions VALUES(1,'Charge1',100,NULL);
INSERT INTO dbo.Transactions VALUES(0,'Payment1',-80,NULL);
INSERT INTO dbo.Transactions VALUES(0,'Payment2',-15,NULL);
INSERT INTO dbo.Transactions VALUES(1,'Charge3',200,NULL);
INSERT INTO dbo.Transactions VALUES(0,'Payment4',-20,NULL);
INSERT INTO dbo.Transactions VALUES(0,'Payment5',-80,NULL);
INSERT INTO dbo.Transactions VALUES(0,'Payment6',-105,NULL);
SELECT * FROM dbo.transactions
SELECT SUM(Amount) FROM dbo.Transactions;
SELECT SUM(Amount) FROM dbo.Transactions WHERE TrxType=1;
SELECT SUM(Amount) FROM dbo.Transactions WHERE TrxType=0;
-- CORRECT APPLICATION
UPDATE dbo.Transactions SET ApplyTo=1 WHERE TrxID IN(2,5)
UPDATE dbo.Transactions SET ApplyTo=4 WHERE TrxID IN(3,6,7)
-- The global balance is zero
SELECT SUM(Amount) FROM dbo.Transactions
-- Both charges have zero balance
SELECT t.*,t.Amount+b.Balance 'Balance'
FROM dbo.Transactions t
OUTER APPLY (SELECT SUM(t2.Amount)Balance
FROM dbo.Transactions t2
WHERE t.TrxID=t2.ApplyTo
)b
-- WRONG APPLICATION
UPDATE dbo.Transactions SET ApplyTo=1 WHERE TrxID IN(2,3,5)
UPDATE dbo.Transactions SET ApplyTo=4 WHERE TrxID IN(6,7)
-- The global balance is zero
SELECT SUM(Amount) FROM dbo.Transactions
-- Charges dont have correct balance, as they could be both zero if applied correctly
SELECT t.*,t.Amount+b.Balance 'Balance'
FROM dbo.Transactions t
OUTER APPLY (SELECT SUM(t2.Amount)Balance
FROM dbo.Transactions t2
WHERE t.TrxID=t2.ApplyTo
)b
谢谢。
【问题讨论】:
-
您应该在第一个插入语句中收到“提供的列数小于表中的列数...”的错误
-
对收费的优化是一个奇怪的要求。在正常的会计情况下,第 2 行和第 3 行以及第 5 行中的 5 美元将应用于第一次收费。第 5 行的其余部分 + 其余部分将适用于第二次收费。否则,您最终可能会遇到无法均匀支付款项的情况。例如,如果您总共有 20 笔付款,每笔 15 美元,您将如何应用它们?
-
您所寻找的似乎类似于打包算法,这是一类单独的问题,具有一些复杂的理论问题。不过,它被简化为它只是一个一维打包问题。你可能想看看Gert-Jan's SQL Server Bin Packing solutions
-
@Anand 第一列是标识,所以它会自动插入。
-
@Anand - 我很惊讶,但我测试了代码,它在 SQL 2012 中工作。我一定错过了这个变化。
标签: sql sql-server cursor balance