2013-05-22 36 views
0

我已經獲得了一個任務來生成帳戶的欠款報告。通過結果集向後SQL Server循環

除了1列DaysInArrears,這是相當直接的。

我已經創建了一個查詢,計算每次預定付款的帳戶的欠款狀態。

此查詢填充的臨時表(#ArrearsAnalysis)的結果類似下面:從下列查詢填充

AgreementID DueDate  AmountDue DueTD PaidTD FirstPaymentDue ArrearsStatus RN 
184   2013-03-11 75.00  75.00 0.00 2013-03-11  1    1 
184   2013-03-25 75.00  150.00 0.00 2013-03-11  1    2 
184   2013-04-08 75.00  225.00 300.00 2013-03-11  0    3 
184   2013-04-22 75.00  300.00 300.00 2013-03-11  0    4 
184   2013-05-03 75.00  375.00 300.00 2013-03-11  1    5 
184   2013-05-20 75.00  450.00 300.00 2013-03-11  1    6 

我也有另一個臨時表(#ArrearsCheck):

INSERT INTO #ArrearsCheck 
SELECT 
    AgreementID, 
    SUM(ArrearsStatus), 
    MAX(RN) 
FROM 
    #ArrearsAnalysis 
GROUP BY 
    AgreementID 

然後,我需要做的是向後查看整個行,以確定何時落入最新拖欠(拖欠分數1)

因此對於考試上面我會預計03/05/2013的結果。

如果一個帳戶從未有過付款,那麼我會返回FirstPaymentDue日期。 如果一個賬戶從來沒有拖欠,那麼我只會返回NULL

這是我迄今爲止的查詢處理非付款人和非欠款,我只需要幫助與循環制定出上述(用* *突出顯示) ):

SELECT 
    DISTINCT(A.AgreementID), 
    CASE WHEN (C.ArrearsTally <= 0) 
    THEN NULL 
    ELSE (CASE WHEN (C.ArrearsTally = C.PaymentCount) 
      THEN NULL 
      *ELSE 0* 
      END) 
    END AS ArrearsDate 
FROM 
    #ArrearsAnalysis AS A 
LEFT OUTER JOIN 
    #ArrearsCheck AS C ON A.AgreementID = C.AgreementID 

此查詢,然後我會把我的下一個查詢將計算今天與結果日期之間的差值(天)的結果。

回答

1

如果我們可以相信RN(行號?)是順序編號的,那麼我們正在尋找兩個相鄰的記錄,其中最近的記錄具有ArrearsStatus = 1並且前面的記錄具有ArrearsStatus = 0(或者不存在,例如空值)。我們希望與最近這樣的事件相關聯的ArrearsStatus = 1的記錄日期:

SELECT MAX(aa1.DueDate) AS MaxDueDate 
FROM #ArrearsAnalysis aa1 
LEFT JOIN #ArrearsAnalysis aa2 
ON aa2.RN = aa1.RN - 1 
WHERE aa1.ArrearsStatus = 1 
AND (aa2.ArrearsStatus = 0 OR aa2.ArrearsStatus IS NULL) 

如果我們不能相信RN,我們將不得不開始與基於日期連接條件(ON AA2。 DueDate < aa1.DueDate),然後找到其他方式建立鄰接關係。 (可能是在中間日期的第三次自加入,然後堅持中間日期爲NULL ...)

基於集合的方法通常比循環更好。在這種情況下,只有當數據最終使基於集合的方法不切實際時,我纔會使用遊標循環。您可以添加aa1.AgreementID分組。我認爲我們不需要#ArrearsCheck。

UPDATE

上面的答案適用於最初表述爲這個問題:「工作時,他們陷入了最新的欠款」。關於「最早拖欠」的問題實際上更有趣一點。我們不能只切換到MIN(),因爲我們希望只有在AgreementID從開始處拖欠時纔會看到初始DueDate,並且從未發生過從0到1的轉換。

最直接的解決方案期待我找到每個案例的MIN()日期,然後選擇這兩個值的MAX()。空值應該退出聚合。

SELECT b.AgreementID, 
MAX(b.MinDueDate) AS FirstArrearsDate 
FROM (
SELECT aa1.AgreementID, 
MIN(aa1.DueDate) AS MinDueDate 
FROM #ArrearsAnalysis aa1 
LEFT JOIN #ArrearsAnalysis aa2 
ON aa2.RN = aa1.RN - 1 
WHERE aa1.ArrearsStatus = 1 
AND aa2.ArrearsStatus = 0 
GROUP BY aa1.AgreementID 
UNION ALL 
SELECT aa1.AgreementID, 
MIN(aa1.DueDate) AS MinDueDate 
FROM #ArrearsAnalysis aa1 
LEFT JOIN #ArrearsAnalysis aa2 
ON aa2.RN = aa1.RN - 1 
WHERE aa1.ArrearsStatus = 1 
AND aa2.ArrearsStatus IS NULL 
GROUP BY aa1.AgreementID 
) AS b 
GROUP BY b.AgreementID 
+0

嗨 行號是正確的,並且可以信任。 我遇到的問題是我需要協議陷入拖欠的最早日期,而不是最後一次。儘管如此,我只想知道0之後的最早的1,而不是最早的1,如果你明白我的意思。 我剛剛將代碼粘貼到我的查詢(上面)* *處,並添加到aa1.AgreementID = A.AgreementID中,結果如上所示,結果爲1900-01-01。 –

+0

@Richard我添加了更新 – criticalfix