日期:2014-05-17  浏览次数:20995 次

求教一句关于连续天数的问题
有如下场景,需要求 从系统时间往前的N天内,有连续M天交易笔数小于等于B笔的商户
参数 N,M ,B 都是根据商户所在地区分开设置的,每个地区按照自己的参数统计
参数表 prm_tbl zoneno 地区和 N ,M B
有一张表记录着 商户每天的交易情况 acc_tbl ,里面字段是 d_date交易日期,merch 商户编号 ,cnt 交易笔数, 这里 如果商户当天没有交易,则不记录在这张表里(但是当天商户的记录算为0笔)
需要筛选的商户 列表 在 merch_list中 表结构 merch 商户编号 ,zoneno商户所在地区号
这个问题 难点有如下几点
1 acc_tbl 中日期可能不连续,因此对于商户当天没有交易的情况应当补全了再统计
2 而每个地区设置的N不一样,补全有难度
3 对于 acc_tbl 中某个商户 A,如果有两条记录 比方说 日期是 20131218,交易笔数4,日期是 20131219,交易笔数3 , 系统时间20131220 商户所在地区对应的参数 N为10,M为 4 ,B为 6,虽然 交易笔数小于 参数B(6),但是 由于acc_tbl 中只有两条记录,其最小的交易时间是 20131218,只有两天满足小于B笔,(而补全日期的话 应该是从 20131211~20131220,没有的记录补0),统计起来应该根据acc_tbl中某商户的最小日期与 系统时间往前算参数N天取最大的那个日期去补全, 因此该商户不应筛选

请问各位大侠,这样的sql怎么写,谢谢!

------解决方案--------------------
3楼的代码没办法做到检测连续。请看新代码:

with all_data as(  
select ml.zoneno, ml.merch, date_id, nvl(tran_cnt,0) tran_cnt, row_number() over(partition by ml.zoneno, ml.merch order by date_id desc) rn from  
(select acc.merch, dates.date_id, nvl(acc.cnt,0) tran_cnt  from acc_tbl acc partition by (merch) right outer join (select trunc(sysdate) - level date_id from dual connect by level <= (select max(last_days) from prm_tbl)) dates  
on acc.d_date=dates.date_id) merch_dates partition by (merch, date_id) right outer join merch_list ml on merch_dates.merch=ml.merch  
),  
filtered_data as(  
select ad.*, pt.min_days,pt.min_trans, 
(case when ad.tran_cnt <= pt.min_trans then 1 else 0 end) ind,
sum((case when ad.tran_cnt <= pt.min_trans then 1 else 0 end)) over(partition by ad.zoneno, ad.merch) sum_ind
from all_data ad, prm_tbl pt  
where ad.zoneno=pt.zoneno  
and ad.rn <= pt.last_days  
),
--select * from filtered_data;
sparse_data as(
select zoneno, merch,rn, nvl(lag(rn, 1) over(partition by zoneno, merch order by date_id desc),0) pre_rn
from filtered_data
where ind=1
)
select distinct zoneno, merch from sparse_data
where rn - pre_rn =1;