Você pode usar a função ROW_NUMBER() aqui:
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
Essa é apenas a data de pagamento mais recente de cada mês, se você quiser por LoanID, adicione LoanID ao
PARTITION BY
Lista. Se você estiver interessado em preservar laços, você pode usar RANK()
em vez de ROW_NUMBER()