从每个月获取最后记录

时间:2013-07-02 22:29:27

标签: sql sql-server-2008 tsql greatest-n-per-group

不幸的是,SQL并不是很容易找到我。我有两个表,一个Loan表和一个LoanPayments表。

LoanPayments表:

  

ID(主键),LoanID(与贷款表上的ID匹配),PaymentDate,Amount等。

我需要一个sql语句,可以给我每个月输入的最后一笔付款(如果有的话)。我目前的陈述并没有给我结果。还有一个问题是,有时候那个月的最大日期会有一个平局,所以我也需要能够处理这个问题(我的想法是在平局的情况下选择最大的ID)。

这是我到目前为止(我知道这是错的,但我不知道为什么。):

SELECT lp.ID, lp.LoanID, lp.PaymentDate 
FROM LoanPayments lp 
WHERE lp.PaymentDate in (
                          SELECT DISTINCT MAX(PaymentDate) as PaymentDate 
                          FROM LoanPayments 
                          WHERE IsDeleted = 0
                          AND ReturnDate is null 
                          GROUP BY YEAR(PaymentDate), Month(PaymentDate)
                        ) 
AND CAST(PaymentDate as date) >= CAST(DATEADD(mm, -24, GETDATE()) as date)

最后一部分只是过滤它,所以我只收到过去24个月的付款。感谢您的帮助,并花时间帮我解决这个问题。

2 个答案:

答案 0 :(得分:7)

您可以在此处使用ROW_NUMBER()函数:

SELECT *
FROM (SELECT lp.ID, lp.LoanID, lp.PaymentDate
          , ROW_NUMBER() OVER (PARTITION BY YEAR(PaymentDate), Month(PaymentDate) ORDER BY PaymentDate DESC) 'RowRank'
      FROM LoanPayments lp 
     )sub
WHERE RowRank = 1

这只是每个月最近的PaymentDate,如果你想通过LoanID,你可以将LoanID添加到PARTITION BY列表中。如果您对保留关系感兴趣,可以使用RANK()代替ROW_NUMBER()

答案 1 :(得分:0)

步骤1:使用窗口函数添加按月保存最大PaymentDate的列

SELECT
  ID,
  LoanID,
  PaymentDate,
  MAX(PaymentDate) OVER(PARTITION BY YEAR(PaymentDate), MONTH(PaymentDate)) AS MaxPaymentDate,
  ROW_NUMBER() OVER(PARTITION BY PaymentDate ORDER BY ID) AS TieBreaker
FROM LoanPayments 
WHERE IsDeleted = 0
AND ReturnDate is null

第2步:将这些结果过滤到您想要的行

SELECT ID,LoanID,PaymentDate
FROM (
  SELECT
    ID,
    LoanID,
    PaymentDate,
    MAX(PaymentDate) OVER(PARTITION BY YEAR(PaymentDate), MONTH(PaymentDate)) AS MaxPaymentDate,
    ROW_NUMBER() OVER(PARTITION BY PaymentDate ORDER BY ID) AS TieBreaker
  FROM LoanPayments 
  WHERE IsDeleted = 0
  AND ReturnDate is null
) t1
WHERE PaymentDate = MaxPaymentDate AND TieBreaker = 1

此方法比进行自联接更有效。