现有一个表如下
人员id  开始时间    结束时间    月租金  总租金
ID kssj     jssj        zj
1 2002-1-1 10
1 2002-2-1 20
1 2005-2-1 30
2 2002-1-1 20
2 2003-1-1 30
3 2000-1-1 5
3 2000-3-1 10
3 2001-3-1 15
3 2004-1-1 20想实现如下功能:
id为1 的人员开时间是2002-1-1,租金10;租到2月份租金变为20;再到2005-2-1租金又变为30;由于结束时间为空,想算出各个阶段总租金得先得出各个阶段的结束时间,我尝试了用游标实现,但是没有做到各位高手请帮忙!2005-2-1后没有时间的话算到当前日期。因为数据都记录在同一张表中,量特别大,所以得想个算法出来解决一下!分多步走都没有问题。

解决方案 »

  1.   

    因为条数不定,我现在的困扰是如何把人员1的2002-1-1开始时间后正确的对应上jssj2002-2-1!
      

  2.   

    --思路,使用分析函数lead()取得下一行的开始时间作为当前的结束时间
    --按月算租金,如果不足1月按1月算;并且id分类汇总,最后时间默认当前时间
    with test as(
      select 1 id, date '2002-1-1' kssj, 10 zj from dual union all
      select 1 id, date '2002-2-1' kssj, 20 zj from dual union all
      select 1 id, date '2005-2-1' kssj, 30 zj from dual union all
      select 2 id, date '2002-1-1' kssj, 20 zj from dual union all
      select 2 id, date '2003-1-1' kssj, 30 zj from dual union all
      select 3 id, date '2000-1-1' kssj, 5  zj from dual union all
      select 3 id, date '2000-3-1' kssj, 10 zj from dual union all
      select 3 id, date '2001-3-1' kssj, 15 zj from dual union all
      select 3 id, date '2004-1-1' kssj, 20 zj from dual)
    select id, sum(ceil(months_between(jssj, kssj)) * zj) total
      from (select t.*,
                   nvl(lead(kssj) over(partition by id order by kssj),
                       trunc(sysdate)) jssj
              from test t)
     group by id;
      

  3.   

    楼上的是正确的 我也给个类似的写法:with bt as(
      select 1 id, date '2002-1-1' kssj, 10 zj from dual union all
      select 1 id, date '2002-2-1' kssj, 20 zj from dual union all
      select 1 id, date '2005-2-1' kssj, 30 zj from dual union all
      select 2 id, date '2002-1-1' kssj, 20 zj from dual union all
      select 2 id, date '2003-1-1' kssj, 30 zj from dual union all
      select 3 id, date '2000-1-1' kssj, 5  zj from dual union all
      select 3 id, date '2000-3-1' kssj, 10 zj from dual union all
      select 3 id, date '2001-3-1' kssj, 15 zj from dual union all
      select 3 id, date '2004-1-1' kssj, 20 zj from dual)select id, sum(zzj)
      from (select tt.*,
                   zj * MONTHS_BETWEEN(nvl(jssj, trunc(sysdate, 'mm')), kssj) zzj
              from (select bt.*,
                           lead(kssj) over(partition by id order by kssj) jssj
                      from bt) tt) ttt
     group by id
      

  4.   

    我想要的结果就是:
    ID kssj    jssj         zj
    1 2002-1-1 2002-2-1     10
    1 2002-2-1 2005-2-1     20
    1 2005-2-1 sysdate      30
    2 2002-1-1 2003-1-1     20
    2 2003-1-1 sysdate      30
    3 2000-1-1 2000-3-1      5
    3 2000-3-1 2001-3-1     10
    3 2001-3-1 2004-1-1     15
    3 2004-1-1 sysdate      20====就是想把同一个id的时间串起来,这样好计算每一段时间的租金,而原来数据表里截止时间是没有的,都是通过程序来判定的。