问题概述:
1. 求tsql存储过程,输入参数@khh(客户号),@jkh(借款号),@jxrq(计息日期), 输出参数@lx(利息)
2. 要能求出任一“给定客户号,给定借款号,给定日期”的利息
说明,下面附图中上面表中有个“到期日期”,还有“利率”和“过期利率”,显见,当@jxrq(计息日期)大于“到期日期”时用“过期利率”而不是“利率”来计算利息。
详见下图下面举例说明一个利息计算的过程:(为了看着清楚,我加了换行)
例1:
设@jxrq(计息日期)=2008.07.05,则
@lx(利息)=
(2008.07.04-2008.07.02)*0.001(利率)*100(上期余额)+
(2008.07.05-2008.07.04)*0.001(利率)*90(上期余额)例2:
设@jxrq(计息日期)=2008.07.13,则
@lx=
(2008.07.04-2008.07.02)*0.001*100+
(2008.07.06-2008.07.04)*0.001*90+
(2008.07.10-2008.07.6)*0.001*70+
(2008.07.12-2008.07.10)*0.001*40+
(2008.07.13-2008.07.12)*0.002*40

请注意红色的两行,由于2008.07.12是到期时间,所以2008.07.10--2008.07.13这段时间被以不同利息计算利息,所以得是两行。例3:
设@jxrq(计息日期)=2008.07.15,则
@lx=
(2008.07.04-2008.07.02)*0.001*100+
(2008.07.06-2008.07.04)*0.001*90+
(2008.07.10-2008.07.6)*0.001*70+
(2008.07.12-2008.07.10)*0.001*40+
(2008.07.[color=#FF0000]15
-2008.07.12)*0.002*40[/color]
请注意红色的两行,由于2008.07.12是到期时间,所以2008.07.10--2008.07.13这段时间被以不同利息计算利息,所以得是两行。
这个例子唯一的不同就是计息时间大于最后一次还款的时间。
请大侠们指教!

解决方案 »

  1.   

    的确,数据太多不好建立,我把两表中用到的数据建立了,凡未列出的列,都是在本任务中不需要的列
    create table jk (khh int,jkh int,jksj datetime,dqsj datetime,ll float,gqll float,jkje money)
    insert jk (khh,jkh,jksj,dqsj,ll,gqll,jkje) values select 1,1,'2008.7.1','2008.7.12',0.001,0.002,100create table hk (khh int,jkh int,sqsj datetime,sqye money,hksj datetime)
    insert hk (khh,jkh,sqsj,sqye,hksj) values select 1,1,'2008.7.2',100,'2008.7.4'
    union 
    select 1,1,'2008.7.4',90,'2008.7.6'
    union 
    select 1,1,'2008.7.6',70,'2008.7.10'
    union 
    select 1,1,'2008.7.10',40,'2008.7.14'
      

  2.   

    请注意,还有一种特殊的计息情况,那就是:
    还款表(hkb)中对应某一khh+hkh一行也没有,也就是说该笔借款从借出一次也没还过,这时计息公式应该是
    (计息时间-借款时间)*利率(或过期利率)*借款金额
    然而上面的计息时间如果大于“到期时间”,也要折成两个公式,一个用“利率”,一个用“过期利率”分别计算。
      

  3.   


    --try
    declare @jk table(khh int,jkh int,jksj datetime,dqsj datetime,ll float,gqll float,jkje money) 
    insert @jk (khh,jkh,jksj,dqsj,ll,gqll,jkje) 
    select 1,1,'2008.7.1','2008.7.12',0.001,0.002,100 
    union all
    select 2,2,'2008.7.3','2008.7.18',0.003,0.004,500 -- 新加上的,,declare @hk table(khh int,jkh int,sqsj datetime,sqye money,hksj datetime) 
    insert @hk (khh,jkh,sqsj,sqye,hksj)  select 1,1,'2008.7.2',100,'2008.7.4' 
    union 
    select 1,1,'2008.7.4',90,'2008.7.6' 
    union 
    select 1,1,'2008.7.6',70,'2008.7.10' 
    union 
    select 1,1,'2008.7.10',40,'2008.7.14' --select * from @jk j
    --left join
    select isnull(h.khh,j.khh) as khh,isnull(h.jkh,j.jkh) as jkh,
    sum(
    case when j.dqsj >=isnull(h.sqsj,getdate())
             then datediff(day,isnull(h.sqsj,getdate()),j.dqsj)*isnull(h.sqye,j.jkje)*j.ll
             else datediff(day,j.dqsj ,isnull(h.sqsj,getdate()))*isnull(h.sqye,j.jkje)*j.gqll end
    )
    as ll
    from @hk h
    full join @jk j on j.khh =h.khh and j.jkh = h.jkh
    group by isnull(h.khh,j.khh),isnull(h.jkh,j.jkh)
    /*
    khh         jkh         ll
    ----------- ----------- ----------------------
    1           1           2.22
    2           2           18
    */
      

  4.   

    再一个
    大侠的程序中没有提到“@jxsj(计息时间)”,利息和计息时间是息息相关的
      

  5.   

    declare @jxrq datetime
    select @jxrq='2008.07.16'
    select hk.khh,hk.jkh,sum(datediff(d,hk.sqsj,case when hk.hksj>jk.dqsj then jk.dqsj when hk.hksj>@jxrq then @jxrq else hk.hksj end)*jk.ll*hk.sqye+
    (case when hk.hksj>jk.dqsj then datediff(d,jk.dqsj,@jxrq)*jk.gqll*hk.sqye else 0 end))利息
    from hk left join jk on jk.khh=hk.khh and jk.jkh=hk.khh 
    where hk.khh=1 and hk.jkh=1 and hk.sqsj<=@jxrq
    group by hk.khh,hk.jkh
      

  6.   

    create proc pro_lx @khh int,@jkh int,@jxrq datetime,@lx float output as 
    select @lx=sum(datediff(d,hk.sqsj,case when hk.hksj>jk.dqsj then jk.dqsj when hk.hksj>@jxrq then @jxrq else hk.hksj end)*jk.ll*hk.sqye+
    (case when hk.hksj>jk.dqsj then datediff(d,jk.dqsj,@jxrq)*jk.gqll*hk.sqye else 0 end))
    from hk left join jk on jk.khh=hk.khh and jk.jkh=hk.khh 
    where hk.khh=1 and hk.jkh=1 and hk.sqsj<=@jxrq
    group by hk.khh,hk.jkh
    -----------调用
    declare @lx float
    exec pro_lx 1,1,'2008.07.15',@lx output
    select @lx--0.98
    exec pro_lx 1,1,'2008.07.13',@lx output
    select @lx--0.82
    exec pro_lx 1,1,'2008.07.05',@lx output
    select @lx--0.29
      

  7.   

    --sorry,写成存储过程时忘了改两个参数
    create proc pro_lx @khh int,@jkh int,@jxrq datetime,@lx float output as 
    select @lx=sum(datediff(d,hk.sqsj,case when hk.hksj>jk.dqsj then jk.dqsj when hk.hksj>@jxrq then @jxrq else hk.hksj end)*jk.ll*hk.sqye+
    (case when hk.hksj>jk.dqsj then datediff(d,jk.dqsj,@jxrq)*jk.gqll*hk.sqye else 0 end))
    from hk left join jk on jk.khh=hk.khh and jk.jkh=hk.khh 
    where hk.khh=@khh and hk.jkh=@jkh and hk.sqsj<=@jxrq
    group by hk.khh,hk.jkh
    -----------调用
    declare @lx float
    exec pro_lx 1,1,'2008.07.15',@lx output
    select @lx--0.98
    exec pro_lx 1,1,'2008.07.13',@lx output
    select @lx--0.82
    exec pro_lx 1,1,'2008.07.05',@lx output
    select @lx--0.29
      

  8.   

    “@jxsj(计息时间)”这个加个限制条件,在查询中对应的修改一下就行了.
    关于其它两个参数,
    只是查询的条件而已,
      

  9.   

    把你14楼的代码复制到查询分析器里,按下F5报错:
    服务器: 消息 134,级别 15,状态 1,过程 pro_lx,行 9
    变量名 '@lx' 已声明。变量名在批查询或存储过程内部必须唯一。
      

  10.   

    谢谢回复,是我太菜
    我在“----------调用”的上面加了go
    出错信息是:
    (1 行受影响)
    消息 208,级别 16,状态 1,过程 pro_lx,第 2 行
    对象名 'hk' 无效。
      

  11.   

    create proc pro_lx @khh int,@jkh int,@jxrq datetime,@lx float output as 
    select @lx=sum(datediff(d,hk.sqsj,case when hk.hksj>jk.dqsj then jk.dqsj when hk.hksj>@jxrq then @jxrq else hk.hksj end)*jk.ll*hk.sqye+ 
    (case when hk.hksj>jk.dqsj then datediff(d,jk.dqsj,@jxrq)*jk.gqll*hk.sqye else 0 end)) 
    from hk left join jk on jk.khh=hk.khh and jk.jkh=hk.khh 
    where hk.khh=@khh and hk.jkh=@jkh and hk.sqsj <=@jxrq 
    group by hk.khh,hk.jkh 
    go
    -----------调用 
    declare @lx float 
    exec pro_lx 1,1,'2008.07.15',@lx output 
    select @lx--0.98 调用成功后的结果
    exec pro_lx 1,1,'2008.07.13',@lx output 
    select @lx--0.82 
    exec pro_lx 1,1,'2008.07.05',@lx output 
    select @lx--0.29
    ---------------------
    我就是用了你4楼给的表:
    create table jk (khh int,jkh int,jksj datetime,dqsj datetime,ll float,gqll float,jkje money) 
    insert jk (khh,jkh,jksj,dqsj,ll,gqll,jkje) select 1,1,'2008.7.1','2008.7.12',0.001,0.002,100 create table hk (khh int,jkh int,sqsj datetime,sqye money,hksj datetime) 
    insert hk (khh,jkh,sqsj,sqye,hksj) select 1,1,'2008.7.2',100,'2008.7.4' 
    union 
    select 1,1,'2008.7.4',90,'2008.7.6' 
    union 
    select 1,1,'2008.7.6',70,'2008.7.10' 
    union 
    select 1,1,'2008.7.10',40,'2008.7.14' 
    -----hk就是你给的(你没建或被删除了),只不过我去掉了values
      

  12.   

    谢谢回复,哥哥
    但是有一个严重问题:我在四楼的数据写借了,。
    “还款记录”的第一笔(行)的“上期时间”必须得等于“借款记录”的“借款时间”。我把正确的重新写在下面,请注意两个红色的日期相等咬合了(如果和四楼的一样就不行了,两个日期不同,中间就漏算了):
    create table jk (khh int,jkh int,jksj datetime,dqsj datetime,ll float,gqll float,jkje money) 
    insert jk (khh,jkh,jksj,dqsj,ll,gqll,jkje) select 1,1,'2008.7.1','2008.7.12',0.001,0.002,100 create table hk (khh int,jkh int,sqsj datetime,sqye money,hksj datetime) 
    insert hk (khh,jkh,sqsj,sqye,hksj) select 1,1,'2008.7.1',100,'2008.7.4' 
    union 
    select 1,1,'2008.7.4',90,'2008.7.6' 
    union 
    select 1,1,'2008.7.6',70,'2008.7.10' 
    union 
    select 1,1,'2008.7.10',40,'2008.7.14' 
    期待大侠再次回复……
      

  13.   

    今一早上试了下发现以下不正常,其中标红部分日期'2008.07.10'比标绿部分日期大,然而计算出的利息却较小
    declare @lx float 
    exec pro_lx 1,1,'2008.07.9',@lx output 
    select @lx   --0.69
    exec pro_lx 1,1,'2008.07.10',@lx output 
    select @lx   --0.68(这个数应该是0.69+0.07=0.76,比上一个日期多一天,利息倒少了)
    exec pro_lx 1,1,'2008.07.11',@lx output 
    select @lx   --0.76
      

  14.   

    --先改一下存储过程
    alter proc pro_lx @khh int,@jkh int,@jxrq datetime,@lx float output as
    set @lx=0
    select @lx=sum(datediff(d,hk.sqsj,case when hk.hksj>jk.dqsj and jk.dqsj<=@jxrq then jk.dqsj when hk.hksj>@jxrq then @jxrq else hk.hksj end)*jk.ll*hk.sqye+
    (case when hk.hksj>jk.dqsj and @jxrq>jk.dqsj then datediff(d,jk.dqsj,@jxrq)*jk.gqll*hk.sqye else 0 end))
    from hk left join jk on jk.khh=hk.khh and jk.jkh=hk.khh 
    where hk.khh=@khh and hk.jkh=@jkh and hk.sqsj<@jxrq
    group by hk.khh,hk.jkh
    ----------上下分开执行
    -----------调用select * from jk select * from hk 
    declare @lx float
    exec pro_lx 1,1,'2008.07.15',@lx output
    select @lx [2008.07.15]--1.08
    exec pro_lx 1,1,'2008.07.14',@lx output
    select @lx [2008.07.14]--1.0
    exec pro_lx 1,1,'2008.07.13',@lx output
    select @lx [2008.07.13]--0.92
    exec pro_lx 1,1,'2008.07.12',@lx output
    select @lx [2008.07.12]--0.84
    exec pro_lx 1,1,'2008.07.11',@lx output
    select @lx [2008.07.11]--0.8
    exec pro_lx 1,1,'2008.07.10',@lx output
    select @lx [2008.07.10]--0.76
    exec pro_lx 1,1,'2008.07.09',@lx output
    select @lx [2008.07.09]--0.69
    exec pro_lx 1,1,'2008.07.08',@lx output
    select @lx [2008.07.08]--0.62
    exec pro_lx 1,1,'2008.07.07',@lx output
    select @lx [2008.07.07]--0.55
    exec pro_lx 1,1,'2008.07.06',@lx output
    select @lx [2008.07.06]--0.48
    exec pro_lx 1,1,'2008.07.05',@lx output
    select @lx [2008.07.05]--0.39
    exec pro_lx 1,1,'2008.07.04',@lx output
    select @lx [2008.07.04]--0.3
    exec pro_lx 1,1,'2008.07.03',@lx output
    select @lx [2008.07.03]--0.3
    exec pro_lx 1,1,'2008.07.02',@lx output
    select @lx [2008.07.02]--0.1
    exec pro_lx 1,1,'2008.07.01',@lx output
    select @lx [2008.07.01]--0.0