Gar*_*ero 4 sql database oracle optimization database-design
例如:
我有这种情况,我们收到付款,每个家庭单独付款,并注册这些付款的金额DB.
问题是,一个家庭可以将贷款转移bank1到bank2,只有他们有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
分析!
数据:
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)
从上次错过的月份开始,连续付款给您几个月的时间.
| 归档时间: |
|
| 查看次数: |
641 次 |
| 最近记录: |