获取每个月的最后一条记录
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()
【讨论】:
这似乎是我需要的。感谢您的快速回复!以上是关于获取每个月的最后一条记录的主要内容,如果未能解决你的问题,请参考以下文章