难:时间段内含旬从旬表取、含月从月表中取,其他从日表取

color2002 2007-06-13 11:08:42
数据库字段
日表
雨量 日期
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时

...全文
402 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
color2002 2007-06-19
  • 打赏
  • 举报
回复
呵呵,楼上的算法不是太精确,我把现在正在用的贴出来吧,谁有兴趣可以继续完善:


---------------------计算累计雨量 ---------------------------------
/*
(含次雨量 注意日期 次雨量传递过来的日期应为开始日期+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
end

while(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
end

if @n=0 set @n=null
return(@n)
end
go
color2002 2007-06-14
  • 打赏
  • 举报
回复
现在问题是解决了,但就是速度慢,不知各位有什么好的解决办法没有
索引已加 TM stcd
lwl0606 2007-06-14
  • 打赏
  • 举报
回复
看这样行不行
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=0

if 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 .....
end

if 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
end

if 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 .....
end

if 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
end

return @aa
being21 2007-06-14
  • 打赏
  • 举报
回复
要是没有人写,我也写一个,呵呵,这样错了也不难看。
being21 2007-06-14
  • 打赏
  • 举报
回复
哈哈,莫非'字模'等人正在写中。我等等。
color2002 2007-06-13
  • 打赏
  • 举报
回复

---------------------计算累计雨量 ---------------------------------
/*
(含次雨量 注意日期 次雨量传递过来的日期应为开始日期+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


----------------------------------------
这是我写的,比较笨,但结果是正确的
速度比较慢,肯定不能用,但不知如何写或是各位有好的方法
color2002 2007-06-13
  • 打赏
  • 举报
回复
简单一点说,
就是我查询一段日期内的雨量
如果这个日期内包含月 如:
5月3日到7月2日,这里面就包含了6月
5月3日到6月2日,这里面就不包含月了,而是包含了5月中旬和下旬
     即5.11到5月20(中旬) 5.21-5.30(下旬)
5月3日到7月2日,这里面包含6月和5月中旬和下旬
CathySun118 2007-06-13
  • 打赏
  • 举报
回复
没有看明白,你如何取的

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧