获取每个月的最后一条记录

Posted

技术标签:

【中文标题】获取每个月的最后一条记录【英文标题】:Get Last Record From Each Month 【发布时间】:2013-06-30 11:40:35 【问题描述】:

不幸的是,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 个月的付款。感谢您的帮助,感谢您抽出宝贵时间帮助我解决此问题。

【问题讨论】:

SELECT TOP 1 ...[query]... ORDER BY myDateColumn DESC 这应该是声明开头的 TOP 1 吗?因为那只是给了我表格中最新的付款。 您希望每个月只记录一条记录,还是每个 LoanID 每月一条记录? @GoatCO 我希望每个loanID 每月有一条记录(如果存在的话,我会在其他地方处理)。 【参考方案1】:

第 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

这种方法比自连接更有效。

【讨论】:

【参考方案2】:

您可以在这里使用 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()

【讨论】:

这似乎是我需要的。感谢您的快速回复!

以上是关于获取每个月的最后一条记录的主要内容,如果未能解决你的问题,请参考以下文章

获取每个 ID 的最后一条记录

Django按时间序列中的ID过滤和选择每个月的最后一条记录的方法?

获取每个月最后一条记录的值(Django)

获取表中存在的每个日期的第一条和最后一条记录号

java 怎样获取每个月的第一天和最后一天

获取从当前日期到下一个完整月的记录(直到下个月的最后一个日期)mysql [重复]