如何验证是否有12个连续付款

Gar*_*ero 4 sql database oracle optimization database-design

例如:

我有这种情况,我们收到付款,每个家庭单独付款,并注册这些付款的金额DB.

问题是,一个家庭可以将贷款转移bank1bank2,只有他们有12个或更多的连续付款.

例如,如果他们已经注册了付款

oct, nov, dec, jan, feb, mar, apr, may, jun, jul, ago, and sept.
Run Code Online (Sandbox Code Playgroud)

feb没有收到任何付款,计数将重新开始march.

同事们建议,最好的方法是,在每次付款注册中计算总付款额,并在一个int名为的列中注册总顺序付款sequential.

如:

Payment     Family      Bank     Date          Sequential
---------------------------------------------------------
1200        2           1        10-22-2009    1
1200        2           1        11-22-2009    2
.
.
.
1200        2          1        08-22-2010     11
1200        2          1        09-22-2010     12
Run Code Online (Sandbox Code Playgroud)

我认为,必须有一种方法,其中sequential列是不必要的,如果我想验证最后order by Date DESC12行是否是连续的,只有1一个月的差异.

有任何想法吗?

编辑:

  • 将有万人rows在此table.

  • 也更喜欢只有表中的日期并与他们一起工作 application level

Ada*_*sch 5

分析!

数据:

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');
--skip august
--insert into payments values (1200, 2, 1, date '2010-08-08');
insert into payments values (1200, 2, 1, date '2010-09-09');
insert into payments values (1200, 2, 1, date '2010-10-10');
insert into payments values (1200, 2, 1, date '2010-11-11');
--double pay november
insert into payments values (1200, 2, 1, date '2010-11-30');
insert into payments values (1200, 2, 1, date '2010-12-12');
Run Code Online (Sandbox Code Playgroud)

查询:

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 
       )
       -- eliminate multiple payments in month
 where payment_month <> next_payment_month
       -- find a gap
   and add_months(payment_month, 1) <> (next_payment_month)
       -- stop at the first gap
   and rownum = 1
Run Code Online (Sandbox Code Playgroud)

结果:

    FAMILY       BANK PAYMENT_M NEXT_PAYM
---------- ---------- --------- ---------
         2          1 01-JUL-10 01-SEP-10
Run Code Online (Sandbox Code Playgroud)

您可以使用该值在NEXT_PAYMENT_MONTH应用程序级别执行所需的任何比较.


SELECT trunc(MONTHS_BETWEEN(SYSDATE, DATE '2010-01-01')) FROM DUAL
Run Code Online (Sandbox Code Playgroud)

给你几个月 - 这就是我在应用程序级别使用值的意思.

所以这:

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
Run Code Online (Sandbox Code Playgroud)

从上次错过的月份开始,连续付款给您几个月的时间.