希望你能提供帮助。
这是我的表:
Declare @AmtToDistribute float = 500.00
DECLARE @TestTable TABLE(TempID INT IDENTITY(1, 1) NOT NULL,
VicID INT ,
VicOrderedAmt MONEY,
RemainingBalance MONEY,
DistPriority INT,
DistPercentOf DECIMAL(5, 2),
DistributionAmt MONEY
);
INSERT INTO @TestTable ([VicID], [VicOrderedAmt], [RemainingBalance], [DistPriority], [DistPercentOf], [DistributionAmt])
VALUES (2318, 5.00, 5.00, 1, 60.00, 0),
(2319, 50.00, 25, 1, 40.00, 0),
(2320, 500.00, 500.0, 2, 33.00, 0),
(2321, 500.00, 500.0, 2, 33.00, 0),
(2322, 500.00, 500.0, 2, 34.00, 0);
SELECT * FROM @TestTable;
我试图找到一个查询,允许我向第一优先级的每一行分配一个美元金额,直到这些值达到零,然后跳到下一个优先级,直到这些值达到零。问题在于,必须根据DistPercentOf列分配美元金额。例如,优先级为1的2行首先分割金额,VicID获得金额的60%,直到满足VicOrderedAmt,然后第二个VicId获得金额的40%。达到优先级1金额后,请转到优先级2.
我已经看过几个帖子,但是他们只处理一个优先级,我需要先支付一个优先级,然后再转到下一个。
提前致谢。
答案 0 :(得分:0)
尝试这样的事情:
Declare @AmtToDistribute MONEY = 500.00
DECLARE @TestTable TABLE (
TempID INT IDENTITY(1, 1) NOT NULL,
VicID INT ,
VicOrderedAmt MONEY,
RemainingBalance MONEY,
DistPriority INT,
DistPercentOf DECIMAL(5, 2),
DistributionAmt MONEY
);
INSERT INTO @TestTable
(VicID, VicOrderedAmt, RemainingBalance, DistPriority, DistPercentOf, DistributionAmt)
VALUES (2318, 5.00, 5.00, 1, 60.00, 0)
, (2319, 50.00, 25, 1, 40.00, 0)
, (2320, 500.00, 500.0, 2, 33.00, 0)
, (2321, 500.00, 500.0, 2, 33.00, 0)
, (2322, 500.00, 500.0, 2, 34.00, 0);
WHILE 1=1 BEGIN
UPDATE y
SET y.DistributionAmt=y.DistributionAmt+y.CurrentDistributedAmt,
y.RemainingBalance=y.RemainingBalance-y.CurrentDistributedAmt,
@AmtToDistribute=@AmtToDistribute-CurrentDistributedAmt
FROM (
SELECT *,
CASE WHEN @AmtToDistribute<RemainingBalanceForCurrentPriority
THEN CASE
WHEN RemainingBalance<@AmtToDistribute*x.DistPercentOf/TotalDistPercent
THEN x.RemainingBalance
ELSE @AmtToDistribute*x.DistPercentOf/TotalDistPercent
END
ELSE x.RemainingBalance
END AS CurrentDistributedAmt
FROM (
SELECT *, SUM(RemainingBalance) OVER () AS RemainingBalanceForCurrentPriority,
SUM(DistPercentOf) OVER () AS TotalDistPercent
FROM @TestTable WHERE DistPriority=(
SELECT MIN(DistPriority) FROM @TestTable
WHERE RemainingBalance>0
) AND RemainingBalance>0
) x
) y
IF @AmtToDistribute=0 BREAK
IF NOT EXISTS (SELECT * FROM @TestTable WHERE RemainingBalance>0) BREAK
END
select * From @TestTable;
为避免舍入错误,请确保@AmtToDistribute与DistributionAmt列具有相同的数据类型。
稍后编辑(2017年2月12日):
我对上面代码中的UPDATE语句做了一些更正。
此外,考虑使用NUMERIC(19,4)而不是MONEY,因为它具有更好的舍入行为。有关详细信息,请参阅Should you choose the MONEY or DECIMAL(x,y) datatypes in SQL Server?。