Analytics
Data:
create table payments (amount number, family number, bank number, payment_date date ); insert into payments values (1200, 2, 1, date '2010-01-01'); insert into payments values (1200, 2, 1, date '2010-02-02'); insert into payments values (1200, 2, 1, date '2010-03-03'); insert into payments values (1200, 2, 1, date '2010-04-04'); insert into payments values (1200, 2, 1, date '2010-05-05'); insert into payments values (1200, 2, 1, date '2010-06-07'); insert into payments values (1200, 2, 1, date '2010-07-07');
Query:
select * from (select family, bank, trunc(payment_date, 'mon') as payment_month, lead ( trunc(payment_date, 'mon')) over ( partition by family order by payment_date) as next_payment_month from payments order by payment_date desc )
Results:
FAMILY BANK PAYMENT_M NEXT_PAYM ---------- ---------- --------- --------- 2 1 01-JUL-10 01-SEP-10
You can use the value in NEXT_PAYMENT_MONTH to perform any comparison you want at the application level.
SELECT trunc(MONTHS_BETWEEN(SYSDATE, DATE '2010-01-01')) FROM DUAL
gives you a few months - this is what I meant using value at the application level.
So this is:
select trunc( months_between(sysdate, (select next_payment_date from (select family, bank, trunc(payment_date, 'mon') as payment_month, lead ( trunc(payment_date, 'mon')) over ( partition by family order by payment_date) as next_payment_month from payments where family = :family order by payment_date desc ) where payment_month <> next_payment_month and add_months(payment_month, 1) <> (next_payment_month) and rownum = 1 ) ) from dual
Gives you several months with consecutive payments since the last month missed.