Sql server sql-显示我可以支付的所有分期付款
我有一张桌子,上面有许多不同客户的分期付款。每个客户都有可用余额 我想显示客户可以支付的所有分期付款 客户1可用余额400 客户2的可用余额为500 分期付款表:Sql server sql-显示我可以支付的所有分期付款,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我有一张桌子,上面有许多不同客户的分期付款。每个客户都有可用余额 我想显示客户可以支付的所有分期付款 客户1可用余额400 客户2的可用余额为500 分期付款表: Customer ID Instalment amount Available 1 150 400 1 150 400 1 150
Customer ID Instalment amount Available
1 150 400
1 150 400
1 150 400
1 150 400
1 150 400
1 150 400
1 150 400
2 200 500
2 200 500
2 200 500
2 200 500
2 200 500
2 200 500
下面是我想要的结果
Customer ID Instalment amount Available
1 150 400
1 150 400
2 200 500
2 200 500
下面的代码不起作用
DECLARE @DrACAvailable decimal,
@PayAmount decimal,
@RunningTotal decimal
SET @RunningTotal = 0
DECLARE rt_cursor CURSOR
FOR
SELECT T2.PayAmount, T2.DrACAvailable
FROM LoanAutoPayTransactions T2
INNER JOIN LoanAutoPayTransactions T1 on T2.LRAC=T1.LRAC
OPEN rt_cursor
FETCH NEXT FROM rt_cursor INTO @PayAmount, @DrACAvailable
WHILE @@FETCH_STATUS = 0
BEGIN
SET @RunningTotal = @RunningTotal + @PayAmount
IF @RunningTotal >= @DrACAvailable BREAK
UPDATE LoanAutoPayTransactions SET PayAmount=@RunningTotal WHERE StartDate=(SELECT MIN(T2.StartDate) FROM LoanAutoPayTransactions T2 WHERE T2.LRAC=LRAC)
FETCH NEXT FROM rt_cursor INTO @PayAmount, @DrACAvailable
END
CLOSE rt_cursor
DEALLOCATE rt_cursor
虽然我不能完全确定你想要什么,但我试了一下。输出是一个表变量,但可以很容易地更改为更新查询或其他内容。请尝试一下,看看是否能得到您想要的结果:
DECLARE @DrACAvailable decimal,
@PayAmount decimal,
@RunningTotal decimal,
@CustomerID int,
@CurrentCustomerID int
SET @RunningTotal = 0
DECLARE @OutputTable table(
LRAC int,
PayAmount decimal,
DrACAvailable decimal);
DECLARE PaymentCursor CURSOR
FOR
SELECT LRAC, PayAmount, DrACAvailable
FROM LoanAutoPayTransactions ORDER BY LRAC, StartDate
OPEN PaymentCursor
FETCH NEXT FROM PaymentCursor INTO @CustomerID, @PayAmount, @DrACAvailable
WHILE @@FETCH_STATUS = 0
BEGIN
IF @CurrentCustomerID != @CustomerID SET @RunningTotal = 0
SET @CurrentCustomerID = @CustomerID
PRINT 'Processing customer id: ' + CAST(@customerid AS VARCHAR)
SET @RunningTotal = @RunningTotal + @PayAmount
IF @RunningTotal <= @DrACAvailable INSERT @OutputTable (LRAC, PayAmount, DrACAvailable) VALUES (@CustomerID, @PayAmount, @DrACAvailable)
FETCH NEXT FROM PaymentCursor INTO @CustomerID , @PayAmount, @DrACAvailable
END
CLOSE PaymentCursor
DEALLOCATE PaymentCursor
-- Print the output table
SELECT LRAC AS 'Customer ID', PayAmount AS 'Instalment amount', DrACAvailable AS 'Available' FROM @OutputTable
DECLARE@dracavaailable decimal,
@工资金额小数,
@运行总小数,
@客户ID int,
@当前客户ID int
设置@RunningTotal=0
声明@OutputTable表(
LRAC int,
工资金额小数,
可使用的十进制数);
声明付款游标
对于
选择LRAC、PayAmount、DrACAvailable
来自LRAC的LoanAutoPayTransactions订单,起始日期
打开付款游标
从PaymentCursor获取下一个到@CustomerID、@PayAmount、@DrACAvailable
而@@FETCH\u STATUS=0
开始
如果@CurrentCustomerID!=@CustomerID集合@RunningTotal=0
设置@CurrentCustomerID=@CustomerID
打印“正在处理客户id:”+CAST(@customerid为VARCHAR)
设置@RunningTotal=@RunningTotal+@PayAmount
如果@RunningTotal这是一个完整的工作示例,没有游标、任何临时表或表变量表-可以在视图或用户定义的内嵌函数中使用:
SET NOCOUNT ON
GO
DECLARE @DataSource TABLE
(
[CustomerID] BIGINT
,[InstalmentAmount] SMALLINT
,[Available] SMALLINT
)
INSERT INTO @DataSource ( [CustomerID], [InstalmentAmount], [Available])
VALUES (1, 150, 400)
,(1, 150, 400)
,(1, 150, 400)
,(1, 150, 400)
,(1, 150, 400)
,(1, 150, 400)
,(1, 150, 400)
,(2, 200, 500)
,(2, 200, 500)
,(2, 200, 500)
,(2, 200, 500)
,(2, 200, 500)
,(2, 200, 500)
;WITH RankedDataSource ( [RecordID], [CustomerID], [InstalmentAmount], [Available] ) AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY [CustomerID] ORDER BY [CustomerID] ASC) AS [RecordID]
,[CustomerID]
,[InstalmentAmount]
,[Available]
FROM @DataSource
),
DataSource ( [RecordID], [CustomerID], [InstalmentAmount], [Available], [CurrentAvailable], [Level] ) AS
(
SELECT DISTINCT CAST(0 AS BIGINT)
,[CustomerID]
,[InstalmentAmount]
,[Available]
,[Available]
,0 AS [Level]
FROM RankedDataSource
UNION ALL
SELECT RecursiveMember.[RecordID]
,RecursiveMember.[CustomerID]
,RecursiveMember.[InstalmentAmount]
,RecursiveMember.[Available]
,AnchorMember.[CurrentAvailable] - RecursiveMember.[InstalmentAmount]
,AnchorMember.[Level] + 1
FROM RankedDataSource AS RecursiveMember
INNER JOIN DataSource AS AnchorMember
ON RecursiveMember.[CustomerID] = AnchorMember.CustomerID
AND RecursiveMember.[RecordID] = AnchorMember.[Level] + 1
AND AnchorMember.[CurrentAvailable] - RecursiveMember.[InstalmentAmount] > 0
)
SELECT [CustomerID]
,[InstalmentAmount]
,[Available]
FROM DataSource
WHERE [Level] > 0
ORDER BY [CustomerID]
,[InstalmentAmount]
,[Available]
SET NOCOUNT OFF
GO
重要的部分是。在大多数情况下,在游标上使用CTE会导致更好的性能。您可以自由检查最适合您需要的内容。我不明白结果与源表的关系。如何选择结果中每个客户的两行?你能详细说明一下吗?ID为1的客户有400欧元的可用余额。400欧元可以支付多少分期付款。从7笔分期付款中,只有2笔可以支付。150+150=300欧元。他无法支付3次分期付款,因为150+150+150=450欧元还有几个问题:你不想让分期付款的日期(我猜是起始日期)也能告诉客户可以支付哪些分期付款吗?LRAC是客户ID吗?是的,LRAC是客户。不,我不在乎日期