2013-07-15 52 views
3

我有一張桌子,上面有許多來自不同客戶的分期付款。每個客戶都有可用餘額。sql - 顯示我可以支付的所有分期付款

我想顯示客戶可以支付的所有分期付款。

顧客1與可用餘額400 顧客2的可用餘額500

分期表:

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 [email protected] 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 
+0

我不明白結果如何與源表相關。結果如何選擇每個客戶的兩行?你能詳細解釋一下嗎? – jpw

+0

ID爲1的客戶可用餘額爲400歐元。 400歐元可以支付多少次分期付款。從7分期付款只有2可以支付。 150 + 150 = 300歐元。他無法支付3期分期付款,因爲150 + 150 +150 = 450歐元 – Leventis1984

+0

還有一些問題:您是否不希望日期(我猜是開始日期)也無法分辨客戶可以分期付款工資? LRAC是客戶ID嗎? – jpw

回答

1

雖然我不完全確定你想要什麼,但我試了一下。輸出是一個表變量,但它可以很容易地更改爲更新查詢或其他東西。請試一試,看看它是否給出結果你想要的:

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 
+0

謝謝你。工作很好。正在工作 – Leventis1984

+0

高興地幫助:) – jpw

1

這是完全沒有遊標例如,任何臨時表或表變量表 - 它可以在視圖中使用或用戶在線定義功能:

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 

重要的部分是Recursive CTE。在大多數情況下,使用CTE而不是Cursors可以提高性能。您可以自由選擇最適合您的需求。