2013-07-02 2 views
0

К сожалению, SQL не приходит ко мне очень легко. У меня две таблицы, таблица Loan и таблица LoanPayments.Получить последнюю запись за каждый месяц

LoanPayments Таблица:

ID (первичный ключ), LoanID (совпадает с ID по кредиту таблицы), PaymentDate, количество, и т.д.

Мне нужен SQL заявление, что может дать мне последний платеж, введенный каждый месяц (если таковой имеется). Мое текущее заявление не дает мне результатов. Существует также проблема, что иногда в течение этого месяца будет привязка к наибольшей дате, поэтому мне также нужно иметь возможность справиться с этим (моя идея состояла в том, чтобы выбрать самый большой идентификатор в случае галстука).

Это то, что я до сих пор (я знаю, что это неправильно, но я не знаю, почему.):

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 месяцев платежей , Спасибо за вашу помощь и за то, что нашли время, чтобы помочь мне в этом вопросе.

+0

'SELECT TOP 1 ... [query] ... ORDER BY myDateColumn DESC' –

+0

Предполагается, что это ТОП 1 в начале заявления? Потому что это просто дает мне новейший платеж в таблице. – TOlsen

+0

Вы хотите, чтобы только одна запись в месяц или одна запись в месяц за LoanID? –

ответ

6

Вы можете использовать функцию 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()

+0

Кажется, это то, что мне нужно. Спасибо за быстрый ответ! – TOlsen

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 

Этот метод более эффективен, чем самоподключение.

Смежные вопросы