我的表上有分期付款记录,如下所示。最初,本金额被指定为2500,但在一定时期后,金额增加了1000并达到3500.现在应该重新分配付款表。最初为每期分期付款2500,我需要分配该金额,以便新的分期金额为3500.
--Initial Records
CREATE TABLE #LOAN_REPAYMENT
(
TRAN_DATE DATETIME,
INSTALLMENT_NO INT,
PAID_AMOUNT DECIMAL(18,2)
)
INSERT INTO #LOAN_REPAYMENT VALUES ('1/15/2016', 11, 2000)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('2/15/2016', 11, 500)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('3/15/2016', 12, 700)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('3/28/2016', 12, 1800)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('3/28/2016', 13, 2500)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('4/15/2016', 14, 2500)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('4/15/2016', 15, 1500)
GO
CREATE TABLE #LOAN_REPAYMENT_NEW
(
TRAN_DATE DATETIME,
INSTALLMENT_NO INT,
PAID_AMOUNT DECIMAL(18,2)
)
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('1/15/2016', 11, 2000)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('2/15/2016', 11, 500)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('3/15/2016', 11, 700)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('3/28/2016', 11, 300)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('3/28/2016', 12, 1500)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('3/28/2016', 12, 2000)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('3/28/2016', 13, 500)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('4/15/2016', 13, 2500)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('4/15/2016', 13, 500)
GO
INSERT INTO #LOAN_REPAYMENT_NEW VALUES ('4/15/2016', 14, 1000)
GO
答案 0 :(得分:1)
我假设最后一条记录的installment_no
值应为14(结果屏幕截图显示为13,结果代码显示为14)。我在代码注释中包含了对答案的解释。
if object_id('tempdb..#loan_repayment') is not null
drop table #loan_repayment
if object_id('tempdb..#loan_repayment_final') is not null
drop table #loan_repayment_final
CREATE TABLE #LOAN_REPAYMENT
(
TRAN_DATE DATETIME,
INSTALLMENT_NO INT,
PAID_AMOUNT DECIMAL(18,2)
)
--creating the temp table for final results
CREATE TABLE #LOAN_REPAYMENT_FINAL
(
TRAN_DATE DATETIME,
INSTALLMENT_NO INT,
PAID_AMOUNT DECIMAL(18,2),
TRAN_RANK INT,
ITER_VAL INT
)
--inserting inital sample data
INSERT INTO #LOAN_REPAYMENT VALUES ('1/15/2016', 11, 2000)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('2/15/2016', 11, 500)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('3/15/2016', 12, 700)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('3/28/2016', 12, 1800)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('3/28/2016', 13, 2500)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('4/15/2016', 14, 2500)
GO
INSERT INTO #LOAN_REPAYMENT VALUES ('4/15/2016', 15, 1500)
GO
declare @install_no int = (select min(installment_no) from #loan_repayment) --starting installment_no
declare @install_amt decimal(18,2) = 3500.00 --new installment amount
declare @rec_rank int --used in while loop
declare @i int = 0 --used to track iteration of while loop
if object_id('tempdb..#loan_repayment_rank') is not null
drop table #loan_repayment_rank
--adding additional derived columns to the initial sample data
select lr.tran_date
, lr.installment_no
, lr.paid_amount
, sum(lr.paid_amount) over (order by lr.tran_date asc, lr.installment_no asc) as unassigned_amt
, row_number() over (order by lr.tran_date asc, lr.installment_no asc) as tran_rank
into #loan_repayment_rank
from #loan_repayment as lr
while exists (select *
from #loan_repayment_rank as lr
where 1=1
and lr.unassigned_amt > 0)
begin
--finding the highest record rank that should be included in
--the current installment calculation
set @rec_rank = coalesce((select min(lrr.tran_rank)
from #loan_repayment_rank as lrr
where 1=1
and unassigned_amt >= @install_amt)
, (select min(lrr.tran_rank)
from #loan_repayment_rank as lrr
where 1=1
and unassigned_amt > 0))
--adding the necessary records to the fianl output
insert into #loan_repayment_final
select lrr.tran_date
, @install_no + @i as installment_no
, case when lrr.tran_rank < @rec_rank then lrr.paid_amount
when lrr.tran_rank = @rec_rank and lrr.paid_amount = lrr.unassigned_amt then lrr.paid_amount
else @install_amt - (select a.unassigned_amt from #loan_repayment_rank as a where tran_rank = @rec_rank - 1)
end as paid_amount
, lrr.tran_rank
, @i as iter_val
from #loan_repayment_rank as lrr
where 1=1
and lrr.tran_rank <= @rec_rank
and lrr.unassigned_amt > 0
--decrementing the paid amounts on the source temp table
--on the records effected by the current installment calculation
update lr
set lr.paid_amount = lr.paid_amount - lf.paid_amount
from #loan_repayment_final as lf
right join #loan_repayment_rank as lr on lf.tran_rank = lr.tran_rank
where 1=1
and lf.iter_val = @i
--updating the unassigned amount on all records
update lr
set lr.unassigned_amt = case when lr.unassigned_amt <= @install_amt then 0.00
else lr.unassigned_amt - @install_amt
end
from #loan_repayment_rank as lr
--incrementing the iteration
set @i += 1
end
--final output
select lf.tran_date
, lf.installment_no
, lf.paid_amount
from #loan_repayment_final as lf