一个有点复杂的SQL统计,高手们来挑战一下

暖枫无敌
博客专家认证
2011-04-09 08:55:46
现有两张表:
第一张 第二张
RainSite(雨量站表),字段如下: Rain (雨量表),字段如下:
ID SiteName Town ID SiteName RainValue RainTime
1 站点一 乡镇一 1 站点一 8 2011-04-05 8:00:00
.... ...

现在要获取下面这张图的数据:



有必要对这张图说明一下,根据传递过来的一个时间段,来获取数据,难点在常年这列的值
常年:是数据库中Rain表中所有年份的该时间段雨量的总和的平均值。



现求一SQL,根据一个时间段,来获取数据。











...全文
152 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
bihai 2011-04-11
  • 打赏
  • 举报
回复
SUBSTRING (CONVERT(Varchar(50),dated,12),3,4)>='0406' and SUBSTRING (CONVERT(Varchar(50),dated,12),3,4)<='0409'

这个条件就可以不考虑年份过滤数据的,余下的你自己应该会写了吧?!
carychuang 2011-04-11
  • 打赏
  • 举报
回复
create view Rain_V1
(
雨量站,雨量,年份,时段
)
as
select [雨量站], [雨量], CONVERT(varchar(4),year([时间])),right(CONVERT(varchar(20),[时间],20),14)
FROM [实测雨情表];

CREATE FUNCTION Rain_F1
(@bdt varchar(20),
@edt varchar(20))
RETURNS TABLE
AS
BEGIN
RETURN
(

select [雨量站],[年份],sum([雨量]) [雨量] from Rain_V1
where 时段 between @bdt and @edt
group by [雨量站],[年份]
);
END
GO

CREATE FUNCTION Rain_F2 (@bdt varchar(20),
@edt varchar(20))
RETURNS TABLE
AS
RETURN
(
select [雨量站],[年份],sum([雨量]) [雨量] from Rain_V1
where 时段 between @bdt and @edt
group by [雨量站],[年份]
);
GO

coleling 2011-04-11
  • 打赏
  • 举报
回复
是不是这样:

--假定你传入的参数为
declare @sdate datetime, @edate datetime
set @sdate = '2011-04-06 8:00:00'
set @edate = '2011-04-08 8:00:00'

select 雨量站,常年=sum(雨量)/count(distinct year(时间))
from (
select * from #t where dateadd(yy,datediff(yy,时间,@sdate),时间) between @sdate and @edate
) a
group by 雨量站
暖枫无敌 2011-04-11
  • 打赏
  • 举报
回复

表就是这张了,所有字段都在,数据也可以看到
wulg10 2011-04-11
  • 打赏
  • 举报
回复
lz,把表结构,数据写成脚本发下。
有大牛会帮你
叶子 2011-04-10
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 taomanman 的回复:]
SQL code

SELECT aa.雨量站 ,
( az雨量 + bz雨量 + cz雨量 ) / 3 ,
( ap雨量 + bp雨量 + cp雨量 ) / 3
FROM ( SELECT 雨量站 ,
SUM(雨量) AS az雨量 ,
AVG(雨量) AS……
[/Quote]
因为null+任何值都为空
把上面的 都改成这样:
( isnull(az雨量,0) + isnull(bz雨量,0) + isnull(cz雨量,0) ) / 3 



如果当年没有,前一年也没有,后一年还是没有 则为0。

你说要看所有年的,确实还是用函数比较方便取出所在时间段的数据,然后按年分组求和,求个数 ,做商。
没一个雨站都要处理一遍,可以用游标,或是用自定义函数。

你要的是所有存在的年,如果有
叶子 2011-04-10
  • 打赏
  • 举报
回复
给出测试数据,及想要的结果,图上的敲一遍太费劲,而且数据太少。

多给些测试数据,然后告诉根据测试数据,你要什么样的结果,然后我抽时间帮你写一下
暖枫无敌 2011-04-10
  • 打赏
  • 举报
回复
表数据就是上面我贴的那张图上取了,类似效果页面地址:
http://61.191.22.155/hq/DroughtAnalysis/P0301.aspx

按照选定的日期,进行统计
bihai 2011-04-10
  • 打赏
  • 举报
回复
你用DATEADD(yy, 1, '2011-03-06 8:00:00') 年份变成2012年了,自然就会出现NULL了,其实你这数可以在过滤时将年去掉,只取月日做为过滤条件即可!
暖枫无敌 2011-04-09
  • 打赏
  • 举报
回复
关键是常年这个的实现,假如传入的时间段如下:
2011-04-06 8:00:00 至 2011-04-08 8:00:00

数据库中有三年数据,那么常年就是
XXXX-04-06 8:00:00 至 XXXX-04-08 8:00:00 (XXXX年该时段总和)
这里的三年是假设的,应该从数据中读取判断有几年然后各年各个时段的总和/年份个数



暖枫无敌 2011-04-09
  • 打赏
  • 举报
回复

SELECT aa.雨量站 ,
( az雨量 + bz雨量 + cz雨量 ) / 3 ,
( ap雨量 + bp雨量 + cp雨量 ) / 3
FROM ( SELECT 雨量站 ,
SUM(雨量) AS az雨量 ,
AVG(雨量) AS ap雨量
FROM 实测雨情表
WHERE 时间 BETWEEN '2011-03-06 8:00:00' AND '2011-03-16 8:00:00'
GROUP BY 雨量站
) aa
LEFT JOIN ( SELECT 雨量站 ,
SUM(雨量) AS bz雨量 ,
AVG(雨量) AS bp雨量
FROM 实测雨情表
WHERE 时间 BETWEEN DATEADD(yy, 1, '2011-03-06 8:00:00') AND DATEADD(yy, 1,
'2011-03-16 8:00:00')
GROUP BY 雨量站
) bb ON aa.雨量站 = bb.雨量站
LEFT JOIN ( SELECT 雨量站 ,
SUM(雨量) AS cz雨量 ,
AVG(雨量) AS cp雨量
FROM 实测雨情表
WHERE 时间 BETWEEN DATEADD(yy, -1, '2011-03-06 8:00:00') AND DATEADD(yy,
-1, '2011-03-16 8:00:00')
GROUP BY 雨量站
) cc ON aa.雨量站 = cc.雨量站


全是NULL值
叶子 2011-04-09
  • 打赏
  • 举报
回复

SELECT aa.雨站 ,
( az雨量 + bz雨量 + cz雨量 ) / 3 ,
( ap雨量 + bp雨量 + cp雨量 ) / 3
FROM ( SELECT 雨站 ,
SUM(雨量) AS az雨量 ,
AVG(雨量) AS ap雨量
FROM tb
WHERE 时间 BETWEEN 开始时间 AND 结束时间
GROUP BY 雨站
) aa
LEFT JOIN ( SELECT 雨站 ,
SUM(雨量) AS bz雨量 ,
AVG(雨量) AS bp雨量
FROM tb
WHERE 时间 BETWEEN DATEADD(yy, 1, 开始时间) AND DATEADD(yy, 1,
结束时间)
GROUP BY 雨站
) bb ON aa.雨站 = bb.雨站
LEFT JOIN ( SELECT 雨站 ,
SUM(雨量) AS cz雨量 ,
AVG(雨量) AS cp雨量
FROM tb
WHERE 时间 BETWEEN DATEADD(yy, -1, 开始时间) AND DATEADD(yy,
-1, 结束时间)
GROUP BY 雨站
) cc ON aa.雨站 = cc.雨站
暖枫无敌 2011-04-09
  • 打赏
  • 举报
回复


create view Rain_V1
(
雨量站,雨量,年份,时段
)
as
select [雨量站], [雨量], CONVERT(varchar(4),year([时间])),right(CONVERT(varchar(20),[时间],20),14)
FROM [实测雨情表];

CREATE FUNCTION Rain_F1
(@bdt varchar(20),
@edt varchar(20))
RETURNS TABLE
AS
BEGIN
RETURN
(

select [雨量站],[年份],sum([雨量]) [雨量] from Rain_V1
where 时段 between @bdt and @edt
group by [雨量站],[年份]
);
END
GO

CREATE FUNCTION Rain_F2 (@bdt varchar(20),
@edt varchar(20))
RETURNS TABLE
AS
RETURN
(
select [雨量站],[年份],sum([雨量]) [雨量] from Rain_V1
where 时段 between @bdt and @edt
group by [雨量站],[年份]
);
GO



后来实在写不下去了
暖枫无敌 2011-04-09
  • 打赏
  • 举报
回复
可能是我表述不清楚,那个分析表中的常年是数据库中所有年份总和的平均值,打个比方
我现在查2011-04-06 8:00:00 至 2011-04-08 8:00:00数据 还有个比较的年份比如说是2010年
取这个时间段得雨量和统计很方便,比较年份的雨量也可以,但是最重要的是要取常年
常年的意思,举个例子吧,数据中有2009年 2010年 2011年这三年的数据,这个常年的数据是
2009-04-06 8:00:00 至 2009-04-08 8:00:00 假如总和是 100
2010-04-06 8:00:00 至 2010-04-08 8:00:00 假如总和是 150
2011-04-06 8:00:00 至 2011-04-08 8:00:00 假如总和是 250
这三个年份时段雨量总和然后除以3(3年数据)
即常年数据是:(100+150+250)/3 = 150

现在想要最终一条SQL语句,根据条件查出所有站点某个时间段得数据。
暖枫无敌 2011-04-09
  • 打赏
  • 举报
回复
同志们,没这么简单的
haa17 2011-04-09
  • 打赏
  • 举报
回复
select 雨量站,avg(雨量) from RainSite,Rain where RainSite.col=Rain.col and date>='' and date<'' group by 雨量站
叶子 2011-04-09
  • 打赏
  • 举报
回复

SELECT 雨站 ,
SUM(雨量) ,
AVG(雨量)
FROM tb
WHERE 时间 BETWEEN 开始时间 AND 结束时间
GROUP BY 雨站
暖枫无敌 2011-04-09
  • 打赏
  • 举报
回复

简化一下,就从这张表取数据

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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