表T1
流出  流入    时间
100   0     2009-03-01
300   0     2009-04-01
0     200   2009-05-01
0     100   2009-05-03 如何求出下面的结果借款   还款  借款时间        还款时间
100   100  2009-03-01    2009-05-01
300   200  2009-04-01    2009-05-03实际上可以把这个看成是应收的账龄分析,要求不用游标,请教大家有没有什么有效率的SQL?

解决方案 »

  1.   

    SELECT a.流出 贷款, b.流入 还款, a.时间 借款时间, b.时间 还款时间
      FROM (SELECT ROWNUM rn, a.*
              FROM t1 a
             WHERE 流入 = 0) a,
           (SELECT ROWNUM rn, a.*
              FROM t1 a
             WHERE 流出 = 0) b
     WHERE a.rn = b.rn AND a.时间 <= b.时间
    以上暂时没考虑有流出没流入的情况
      

  2.   

    select a.借款,b.还款,a.借款时间,b.还款时间 from
    (select t1.流出 as 借款,t1.时间 as 借款时间,rownum ru from T1 where t1.流入 =0) a,
    (select t1.流入 as 还款,t1.时间 as 还款时间,rownum ru from T1 where t1.流出 =0) b
    where a.ru = b.ru
      

  3.   

    这个 
    借款和还款的金额出现不相等的情况,不能够一次还款就抵消一次借款 
    比如 
    表T1 
    流出  流入    时间 
    100  0    2009-03-01 
    300  0    2009-03-02 
    0    200  2009-03-03 
    0    100  2009-03-04 
    200  0    2009-03-05 
    0    100  2009-03-06 第3条数据是还第一条的吗?可是200超过100了,不用…
    [/Quote]不好意思,看样子是我没说清楚,这个SQL其实就是用来做应收帐龄分析的
    1、如果不能一次还清那么就从后续的还款中取数,直到还清该笔贷款
    2、如果还清了该笔贷款,并且有多的话,那么结余数就扣除下来还下一笔贷款
    3、借款时间不一定小于贷款时间
      

  4.   


    我希望得到的结果,第二笔贷款一直到3月6日才还清 借款  还款  借款时间        还款时间 
    100  100  2009-03-01    2009-03-03 
    300  300  2009-03-02    2009-03-06 
    [/Quote]刚刚贴错了,这个才是
    借款  还款  借款时间        还款时间 
    100  100  2009-03-01    2009-03-03 
    300  300  2009-03-02    2009-03-06
    200  0    2009-03-05      
      

  5.   

    我用的测试表t_test
    字段 fee1,fee2,date1select LOAN_DATE.fee1,
           decode(BACK_DATE.BACK_FEE, null, 0, BACK_DATE.BACK_FEE),
           LOAN_DATE.date1,
           BACK_DATE.BACK_DATE
      from (select fee1, fee2, date1 from t_test where fee2 = 0) LOAN_DATE
      left join (
                 select date1, max(fee1) BACK_FEE, min(date2) BACK_DATE
                   from (select t1.date1,
                                 t1.fee1,
                                 t2.date1 date2,
                                 (select sum(fee2)
                                    from t_test
                                   where fee1 = 0
                                     and date1 <= t2.date1) FEE_BACK,
                                 (select sum(fee1)
                                    from t_test
                                   where fee2 = 0
                                     and date1 <= t1.date1) FEE_LOAN
                            from (select fee1, fee2, date1
                                    from t_test
                                   where fee2 = 0) t1,
                                 (select fee1, fee2, date1
                                    from t_test
                                   where fee1 = 0) t2
                           order by t1.date1, t2.date1)
                  where FEE_BACK >= FEE_LOAN
                  group by date1) BACK_DATE on LOAN_DATE.DATE1 =
                                               BACK_DATE.date1
     order by LOAN_DATE.date1
    执行结果:
    100 100 2009-03-01 2009-03-03
    300 300 2009-03-02 2009-03-06
    200 0 2009-03-05
      

  6.   

    谢谢lihui_shine了,这个SQL思路比较巧妙,反正我是肯定想不出的。
    我再测试一下,看看效率如何,因为(select fee1, fee2, date1
                                    from t_test
                                   where fee2 = 0) t1,
                                 (select fee1, fee2, date1
                                    from t_test
                                   where fee1 = 0) t2
    这个会是一个笛卡尔积的集合,现在手头上有事要忙,晚点给出结果