数据库字段
日表
雨量 日期
1.1   2007-5-6 8:10:00
1.2   2007-5-7 10:10:00
.....
旬表
雨量 日期
1.1   2007-5-1 8:10:00 --代表4月下旬
1.2   2007-5-11 10:10:00 --代表5月上旬
1.2   2007-5-21 10:10:00 --代表5月中旬
.....
月表
雨量 日期
1.1   2007-5-1 8:10:00 --代表4月
1.2   2007-6-1 10:10:00 --代表5月
1.2   2007-7-1 10:10:00 --代表6月
.....
比如从2007-5-6 8:10:00到2007-5-11 8:10:00
从日表中取6日到11日的雨量合计比如从2007-5-6 8:10:00到2007-5-24 8:10:00
从日表中取5月6日到5月10日
再从旬表中取5月21日的旬雨量
再从日表中取5月21日到24日比如从2007-5-6 8:10:00到2007-7-24 8:10:00
从日表中取5月6日到5月10日
再从旬表中取5月21日的旬雨量
再从旬表中取6月1日的旬雨量
再从月表中取7月1日的月雨量
再取7月1日到24日的雨量最后取这些雨量的统计
用函数做(方便其他调用)------------------------
暂时没想到好方法,我准备用循环判断 一天天判断,希望各位能有好方法速度上不应太慢,因为数据量很大------------------------
还有个要求,只是提出来,可不用考虑这个
  每天的数据要判断6、8时,有6时取6时,没6时取8时

解决方案 »

  1.   


    ---------------------计算累计雨量 ---------------------------------
    /*
    (含次雨量 注意日期 次雨量传递过来的日期应为开始日期+1)
    开始结束日期 
    含月的从统计表[ST_PSTAT_R]中取该月的,STTDRCD=5
    除月之外含旬的从统计表中取旬,STTDRCD=4
    其他取日
    最后一天除取68时[DYP]外,还要累加段雨量[DRP] By:table[ST_PPTN_R]
    Date:2007-6-13 10:39:06
    Author: 叶磊
    */
    if exists(select * from sysobjects where name='GetSumRain' and type='FN') drop function GetSumRain
    go
    create   function   GetSumRain(@stcd char(8),@tm1 datetime,@tm2 datetime)--站号 开始日期 结束日期
    returns   float --decimal(10,3)
    as
    begin
    declare   @n float-- decimal(10,3)
    select @n=0
    while(@tm1<=@tm2)
    begin
    if(datename(d,@tm1)=1)--如果当前天为1 先判断是否含月 再判断是否包含上旬
    begin
    if(dateadd(mm,1,@tm1)<=@tm2)--如果当前时间加一个月大于结束时间,说明含月
    begin
    set @tm1=dateadd(mm,1,@tm1) 
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where STCD=@stcd and datediff(d,@tm1,IDTM)=0 and (datename(hh,IDTM)=6 or datename(hh,IDTM)=8) and STTDRCD=5 order by IDTM),0) --累计 
    end
    else--小于月,再判断旬
    begin
    if(dateadd(dd,10,@tm1)<=@tm2)--如果当前时间+10小于结束时间,说明含上旬
    begin
    set @tm1=dateadd(dd,10,@tm1)
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where STCD=@stcd and datediff(d,@tm1,IDTM)=0 and (datename(hh,IDTM)=6 or datename(hh,IDTM)=8) and STTDRCD=4 order by IDTM),0) --累计 
    end
    else --不含旬月数据
    begin
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where STCD=@stcd and datediff(d,TM,@tm1)=0 and (datename(hh,TM)=6 or datename(hh,TM)=8) and TM<=@tm2 and DYP is not null order by TM),0)--累计日
    set @tm1=dateadd(dd,1,@tm1)
    end
    end
    end
    else
    begin
    if(datename(d,@tm1)=11) --当前天为11日判断是否包含中旬
    begin
    if(dateadd(dd,10,@tm1)<=@tm2) --判断旬 不用判断月
    begin
    set @tm1=dateadd(dd,10,@tm1)
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where STCD=@stcd and datediff(d,@tm1,IDTM)=0 and (datename(hh,IDTM)=6 or datename(hh,IDTM)=8) and STTDRCD=4 order by IDTM),0) --累计 
    end
    else--不含旬
    begin
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where STCD=@stcd and datediff(d,TM,@tm1)=0 and (datename(hh,TM)=6 or datename(hh,TM)=8) and TM<=@tm2 and DYP is not null order by TM),0)--累计日
    set @tm1=dateadd(dd,1,@tm1)
    end
    end
    else 
    begin
    if(datename(d,@tm1)=21)  --当前天为21日判断是否包含下旬
    begin
    if( dateadd(mm,1,cast( cast(year(@tm1) as varchar(50))+'-'+cast(month(@tm1) as varchar(50))+'-1 0:00:00' as datetime))<=@tm2) --包含下旬
    begin
    set @tm1=dateadd(mm,1,cast( cast(year(@tm1) as varchar(50))+'-'+cast(month(@tm1) as varchar(50))+'-1 0:00:00' as datetime))
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where STCD=@stcd and datediff(d,@tm1,IDTM)=0 and (datename(hh,IDTM)=6 or datename(hh,IDTM)=8) and STTDRCD=4 order by IDTM),0) --累计 
    end
    else--不含旬
    begin
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where STCD=@stcd and datediff(d,TM,@tm1)=0 and (datename(hh,TM)=6 or datename(hh,TM)=8) and TM<=@tm2 and DYP is not null order by TM),0)--累计日
    set @tm1=dateadd(dd,1,@tm1)
    end
    end
    else
    begin
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where STCD=@stcd and datediff(d,TM,@tm1)=0 and (datename(hh,TM)=6 or datename(hh,TM)=8) and TM<=@tm2 and DYP is not null order by TM),0)--累计日
    set @tm1=dateadd(dd,1,@tm1) end
    end
    end
    --最后一天加时段
      select @n=@n+isnull( (select sum(DRP) from ST_PPTN_R where STCD=@stcd and datediff(d,@tm2,TM)=0 and TM<=@tm2),0)
    end--if @n=0 set @n=null
    return(@n)
    end
    go
     ----------------------------------------
    这是我写的,比较笨,但结果是正确的
    速度比较慢,肯定不能用,但不知如何写或是各位有好的方法
      

  2.   

    现在问题是解决了,但就是速度慢,不知各位有什么好的解决办法没有
    索引已加 TM stcd
      

  3.   

    看这样行不行
    create   function   GetSumRain(@stcd char(8),@tm1 datetime,@tm2 datetime)
    returns   float --decimal(10,3)
    as
    begin
    declare @aa decimal(10,3)
    declare @i int
    declare @j int
    set @aa=0if datediff(m,@tm1,@tm2)>2
     begin 
     select @aa=@aa+雨量  from 月表  where STCD=@stcd  and datepart(m,日期)>datepart(m,@tm1) and datepart(m,日期)<datepart(m,@tm2)
     if datepart(d,@tm1)<20
       select @aa=@aa+雨量  from 旬表  where .....
       select @aa=@aa+雨量  from 日表  where .....
     else 
       select @aa=@aa+雨量  from 日表  where ..... if datepart(d,@tm2)>9
       select @aa=@aa+雨量  from 旬表  where .....
       select @aa=@aa+雨量  from 日表  where .....
     else 
       select @aa=@aa+雨量  from 日表  where .....
    endif  datediff(m,@tm1,@tm2)=1 and (datepart(d,@tm1)<20 or datepart(d,@tm2)>9) --
    begin 
     select @aa=@aa+雨量  from 旬表  where  STCD=@stcd   and Convert(7,日期,23)= Convert(7,@tm1,23) and 日期>=@tm1
     select @aa=@aa+雨量  from 旬表  where  STCD=@stcd   and Convert(7,日期,23)= Convert(7,@tm2,23) and 日期<=@tm2
     select @aa=@aa+雨量  from 日表  where  STCD=@stcd   and 日期>=@tm1 and 日期< Convert(8,@tm1,23)+Convert(nvarchar(1),right(Convert(8,@tm1,23),1)+1)+'0'
     select @aa=@aa+雨量  from 日表  where  STCD=@stcd   and 日期<=@tm2
    end
    if  datediff(m,@tm1,@tm2)=1 and datepart(d,@tm1)>=20 and  datepart(d,@tm2)<=9
    begin
     select @aa=@aa+雨量  from 日表  where  STCD=@stcd  and 日期>=@tm1 and 日期<=@tm2 
    endif  datediff(m,@tm1,@tm2)=0  and right(Convert(8,@tm1,23),1)+1<right(Convert(8,@tm2,23),1)
    begin
       select @aa=@aa+雨量  from 旬表  where .....
       select @aa=@aa+雨量  from 日表  where .....
    endif  datediff(m,@tm1,@tm2)=0  and right(Convert(8,@tm1,23),1)+1>=right(Convert(8,@tm2,23),1)
    begin
     select @aa=@aa+雨量  from 日表  where  STCD=@stcd  and 日期>=@tm1 and 日期<=@tm2 
    endreturn @aa
      

  4.   

    呵呵,楼上的算法不是太精确,我把现在正在用的贴出来吧,谁有兴趣可以继续完善:
    ---------------------计算累计雨量 ---------------------------------
    /*
    (含次雨量 注意日期 次雨量传递过来的日期应为开始日期+1)
    开始结束日期
    含月的从统计表[ST_PSTAT_R]中取该月的,STTDRCD=5
    除月之外含旬的从统计表中取旬,STTDRCD=4
    其他取日
    最后一天除取68时[DYP]外,还要累加段雨量[DRP] By:table[ST_PPTN_R]
    Date:2007-6-13 10:39:06
    Author: 叶磊
    */
    if exists(select * from sysobjects where name='GetSumRain' and type='FN') drop function GetSumRain
    go
    create   function   GetSumRain(@stcd char(8),@tm1 datetime,@tm2 datetime)--站号 开始日期 结束日期
    returns   float --decimal(10,3)
    as
    begin
    declare @curh int --开始日期的小时
    declare   @n float-- decimal(10,3)
    select @n=0
    --create table #m(DYP float) --创建临时表 存储降雨量信息
    --select top 1 @curh=isnull(datename(hh,TM),dbo.getXunQiHour(@tm1)) from ST_PPTN_R where TM>=@tm1 and (datename(hh,TM)=6 or datename(hh,TM)=8) and TM<=@tm2 and STCD=@stcd and DYP is not null order by TM--取出第一天实际的小时数
    set @curh=dbo.getXunQiHour(@tm2)
    if(datediff(d,@tm1,@tm2)=0)--如果是同一天的 取段雨量相加
    begin
      select @n=@n+isnull((select sum(DRP) from ST_PPTN_R where  TM>@tm1 and TM<=@tm2 and STCD=@stcd and DRP is not null),0)
    set @tm1=dateadd(d,1,@tm2) ---让开始时间=结束时间+1天以下面的循环取日雨量
    end
    else --不是同一天的
    begin
    if(datediff(d,@tm1,@tm2)=1) --相差一天的
    begin if( datename(hh,@tm1)<@curh)--开始时间<6  取开始结束与开始时间6时之间的段雨量
    begin
    select  @n=@n+isnull(( select sum(DRP) from ST_PPTN_R where  TM>@tm1 and TM<=dbo.getymr(@tm1)+' '+cast(@curh as varchar(50))+':00:00' and STCD=@stcd and DRP is not null),0)
    set @tm1=dbo.getymr(@tm1)+' '+cast(@curh as varchar(50))+':00:00' --让开始时间=开始时间6时 进行下一步
    end
    if( (datename(hh,@tm1)=@curh and datename(hh,@tm2)<6) or datename(hh,@tm1)>@curh) --如果开始时间=6结束时间小于6 或开始时间>6 取开始时间到结束时间之间的段雨量
    begin
    select  @n=@n+isnull((select sum(DRP) from ST_PPTN_R where TM>@tm1 and TM<=@tm2 and STCD=@stcd and DRP is not null),0)
    select @tm1=dateadd(d,1,@tm2) --让开始时间=结束时间+1天以下面的循环取日雨量
    end
    else--此时只有开始时间=6结束时间>=6 取结束时间与6时之后的段雨量 
    begin
    select  @n=@n+isnull((select sum(DRP) from ST_PPTN_R where TM>dateadd(d,1,@tm1) and TM<=@tm2 and STCD=@stcd and DRP is not null),0)
    select @tm1=dateadd(d,1,@tm1) --让开始时间=结束时间时的6时 这样可在下面的循环中取到日雨量 end
    end
    else--大于2天的
    begin
    if( datename(hh,@tm1)<@curh)--开始时间<6  取开始结束与开始时间6时之间的段雨量
    begin
    select  @n=@n+isnull(( select sum(DRP) from ST_PPTN_R where  TM>@tm1 and TM<=dbo.getymr(@tm1)+' '+cast(@curh as varchar(50))+':00:00' and STCD=@stcd and DRP is not null ),0)
    set @tm1=dbo.getymr(@tm1)+' '+cast(@curh as varchar(50))+':00:00' --让开始时间=开始时间6时 进行下一步
    end
    if( datename(hh,@tm1)>@curh)--开始时间>6  取开始结束与(开始时间+1)6时之间的段雨量 设置开始时间为第二天的6时
    begin
    select  @n=@n+isnull(( select sum(DRP) from ST_PPTN_R where  TM>@tm1 and TM<=dateadd(d,1,dbo.getymr(@tm1)+' '+cast(@curh as varchar(50))+':00:00') and STCD=@stcd and DRP is not null ),0)
    set @tm1=dateadd(d,1,dbo.getymr(@tm1)+' '+cast(@curh as varchar(50))+':00:00') --让开始时间=开始时间6时 进行下一步
    end
    --if(datename(hh,@tm1)=@curh) --如果等于 设置开始时间+1天
    --begin
    -- set @tm1=dateadd(d,1,@tm1)
    --end
    if(datename(hh,@tm2)<@curh)--结束时间小于6 判断前一天6时到结束时间的段雨量 设置结束时间为前一天6时
    begin
    select  @n=@n+isnull(( select sum(DRP) from ST_PPTN_R where  TM>dateadd(d,-1,dbo.getymr(@tm2)+' '+cast(@curh as varchar(50))+':00:00') and TM<=@tm2 and STCD=@stcd and DRP is not null ),0)
    set @tm2=dateadd(d,-1,dbo.getymr(@tm2)+' '+cast(@curh as varchar(50))+':00:00') --让结束时间=结束时间前一天的6时
    end
    else--计算结束时间6时后的段雨量
    begin
    select  @n=@n+isnull( (select sum(DRP) from ST_PPTN_R where TM>dbo.getymr(@tm2)+' '+cast(@curh as varchar(50))+':00:00' and TM<=@tm2 and STCD=@stcd and DRP is not null ),0)
    set @tm2=dbo.getymr(@tm2)+' '+cast(cast(@curh as varchar(50)) as varchar(50))+':00:00' --让开始时间=开始时间6时 进行下一步 end end
    endwhile(datediff(d,@tm1,@tm2)>0)--@tm1<=@tm2)
    begin
    if(datename(d,@tm1)=1)--如果当前天为1 先判断是否含月 再判断是否包含上旬
    begin
    if(dateadd(mm,1,@tm1)<=@tm2)--如果当前时间加一个月大于结束时间,说明含月
    begin
    set @tm1=dateadd(mm,1,@tm1)
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where (IDTM=dbo.getymr(@tm1)+' 6:00:00' or IDTM=dbo.getymr(@tm1)+' 8:00:00') and STCD=@stcd and STTDRCD=5 order by IDTM),0) --累计 end
    else--小于月,再判断旬
    begin
    if(dateadd(dd,10,@tm1)<=@tm2)--如果当前时间+10小于结束时间,说明含上旬
    begin
    set @tm1=dateadd(dd,10,@tm1)
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where (IDTM=dbo.getymr(@tm1)+' 6:00:00' or IDTM=dbo.getymr(@tm1)+' 8:00:00') and STCD=@stcd and STTDRCD=4 order by IDTM),0) --累计 end
    else --不含旬月数据
    begin
    set @tm1=dateadd(dd,1,@tm1)
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where (TM=dbo.getymr(@tm1)+' 6:00:00' or TM=dbo.getymr(@tm1)+' 8:00:00') and TM<=@tm2 and STCD=@stcd and DYP is not null order by TM),0)--累计日 end
    end
    end
    else
    begin
    if(datename(d,@tm1)=11) --当前天为11日判断是否包含中旬
    begin
    if(dateadd(dd,10,@tm1)<=@tm2) --判断旬 不用判断月
    begin
    set @tm1=dateadd(dd,10,@tm1)
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where (IDTM=dbo.getymr(@tm1)+' 6:00:00' or IDTM=dbo.getymr(@tm1)+' 8:00:00') and STCD=@stcd and STTDRCD=4 order by IDTM),0) --累计 end
    else--不含旬
    begin
    set @tm1=dateadd(dd,1,@tm1)
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where (TM=dbo.getymr(@tm1)+' 6:00:00' or TM=dbo.getymr(@tm1)+' 8:00:00') and TM<=@tm2 and STCD=@stcd and DYP is not null order by TM),0)--累计日 end
    end
    else
    begin
    if(datename(d,@tm1)=21)  --当前天为21日判断是否包含下旬
    begin
    if( dateadd(mm,1,cast( cast(year(@tm1) as varchar(50))+'-'+cast(month(@tm1) as varchar(50))+'-1 0:00:00' as datetime))<=@tm2) --包含下旬
    begin
    set @tm1=dateadd(mm,1,cast( cast(year(@tm1) as varchar(50))+'-'+cast(month(@tm1) as varchar(50))+'-1 0:00:00' as datetime))
    select @n=@n+isnull((select top 1 ACCP from ST_PSTAT_R where (IDTM=dbo.getymr(@tm1)+' 6:00:00' or IDTM=dbo.getymr(@tm1)+' 8:00:00') and STCD=@stcd and STTDRCD=4 order by IDTM),0) --累计 end
    else--不含旬
    begin
    set @tm1=dateadd(dd,1,@tm1)
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where (TM=dbo.getymr(@tm1)+' 6:00:00' or TM=dbo.getymr(@tm1)+' 8:00:00') and TM<=@tm2 and STCD=@stcd and DYP is not null order by TM),0)--累计日 end
    end
    else
    begin
    set @tm1=dateadd(dd,1,@tm1)
    select @n=@n+isnull( (select top 1 DYP from ST_PPTN_R where (TM=dbo.getymr(@tm1)+' 6:00:00' or TM=dbo.getymr(@tm1)+' 8:00:00') and TM<=@tm2 and STCD=@stcd and DYP is not null order by TM),0)--累计日
    end
    end
    end
    endif @n=0 set @n=null
    return(@n)
    end
    go