SQL计算日期的笔记(日数据计算)
做的一个项目,要计算每一日的数据统计,以日雨量为例,
每个记录的记录时间包括了时分秒。
计算规则: 日期为8:00到8:00才为一天的数据,
假设要计算2012-03-25的雨量,则数据的日期范围应该是 2012-03-25 08:00:00 到 2012-03-26 8:00:00之间的数据
相到的查询方法是 通过查询日期范围在开始日期和结束日期之间的数据,将日期与开始日期的8:00:00钟开始算它们之间的小时差,根据小时差,进行分组,算日雨量之和
测试数据
create table TestTb
(
id int primary key identity(1,1),
HappenDate varchar(20),
RainNumber int
)
GO
insert into TestTb select '2012-03-22 08:00:00',10
union all select '2012-03-22 09:00:00',10
union all select '2012-03-22 10:02:00',10
union all select '2012-03-22 10:30:00',10
union all select '2012-03-22 11:20:00',10
union all select '2012-03-22 11:30:00',10
union all select '2012-03-22 11:40:00',10
union all select '2012-03-22 11:50:00',10
union all select '2012-03-22 15:00:00',10
union all select '2012-03-22 16:00:00',10
union all select '2012-03-22 17:00:00',10
union all select '2012-03-22 18:00:00',10
union all select '2012-03-22 19:00:00',10
union all select '2012-03-22 20:00:00',10
union all select '2012-03-22 21:00:00',10
union all select '2012-03-22 22:00:00',10
union all select '2012-03-22 23:00:00',10
union all select '2012-03-23 00:20:00',10
union all select '2012-03-23 07:20:00',10
union all select '2012-03-23 08:00:00',50
union all select '2012-03-24 09:00:00',100
union all select '2012-03-21 09:20:20',80
union all select '2012-03-23 09:20:20',80
union all select '2012-03-23 10:20:20',80
union all select '2012-03-26 10:20:20',80
union all select '2012-03-26 07:20:20',80
查询语句(计算2012-03-22到2012-03-26之间的日雨量)
declare @startDate datetime
declare @endDate datetime
declare @hours int
set @startDate='2012-03-22 08:00:00'
set @endDate='2012-03-27 08:00:00'
select @hours=datediff(hh,@startDate,@endDate)
select Sum(RainNumber) as 总数, Convert(varchar(10),(case when datepart(hh,min(HappenDate))<=7 then dateadd(day,-1,min(HappenDate)) else min(HappenDate) end),120) as 日期 from (select
(case when datediff(hh,@startDate,HappenDate) between 0 and 23 then 1
when datediff(hh,@startDate,HappenDate) between 24 and 47 then 2
when datediff(hh,@startDate,HappenDate) between 48 and 71 then 3
when datediff(hh,@startDate,HappenDate) between 72 and 95 then 4
when datediff(hh,@startDate,HappenDate) between 96 and 119 then 5
when datediff(hh,@startDate,HappenDate) between 120 and 143 then 6
else 0
end) as OneDay
,HappenDate,RainNumber from TestTb where datediff(hh,@startDate,HappenDate) between 0 and @hours) as t group by OneDay
碰到的第一问题是:
原来的查询语句分组之后只用了 min(HappenDate)得到日期,发现这是错误的,比如上面测试数据的最后一个日期 2012-03-26 07:20:20 应该是属于 3月25号的雨量,
而数据中 2012-03-25 没有数据,所以 min(HappenDate)对于 2012-03-26 07:20:20这个日期,也只能是3月26日的,有错误,
想到的处理方法是 看这个日期的小时是否为小于等于7,如果是,则日期的天数应该减1,则这个数据日期应该归到3月25日去
(case when datepart(hh,min(HappenDate))<=7 then dateadd(day,-1,min(HappenDate)) else min(HappenDate) end)
第二个问题是:
查询的日期范围是不固定的,所以要动态去生成这个SQL语句,(通过后台代码去构建)
第三个问题:
如果时间跨度很大,则这个SQL语句的长度长到吓死人(比如,跨了几年)
测试,跨3年可以,
跨5年则 SQL语句就过长了 --问题未解决(纠结)