这个SQL如何写才能进行高效统计?

Mr.Osc 2001-09-18 09:52:31
数据表结构如下
id date count
------------------------------
1 2000-9-1 23
2 2000-9-2 20
3 2000-9-3 10
.
.
.
.
29 2000-9-29 11
30 2000-9-29 23
31 2000-10-1 44
.
.
.
.
61 2000-10-31 23
62 2000-11-1 22
.
.
.
.
78 2000-11-17 11
.
.
-----------------------------

现在我想根据用户输入的起始和终止时间来统计count的和
例:
begintime 2000-9-3
endtime 2000-12-17
需要写SQL一次进行分段求和,得到以下的count的值:
2000-9-3至2000-9-30 count的和
2000-10-1至2000-10-31 count的和
2000-11-1至2000-11-30 count的和
2000-12-1至2000-12-17 count的和
但因为数据库在服务器端,所以不想执行多次查询求和,希望能获得一个高效率的方法,请各位高手赐教。一定给分。。
...全文
96 11 打赏 收藏 举报
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
icevi 2001-09-21
to KingSunSha(弱水三千):
Orivan(椰子壳)要的是:
2000-9-3至2000-9-30 count的和
~~~~~~~~~
2000-10-1至2000-10-31 count的和
2000-11-1至2000-11-30 count的和
2000-12-1至2000-12-17 count的和

若表中没有2000-9-30 的记录,9月份只有2000-9-29的记录,
你的语句结果是:
2000-9-3至2000-9-29 count的和
~~~~~~~~~
2000-10-1至2000-10-31 count的和
2000-11-1至2000-11-30 count的和
2000-12-1至2000-12-17 count的和


  • 打赏
  • 举报
回复
KingSunSha 2001-09-19
贴的时候||被自动改成¦¦

To icevi(按钮工厂):
1、若是九月最多只有28 号的记录, 结果会是2000-9-01 至2000-9-28,与Orivan(椰子壳)要的结果可不一样。他要的是每月第一天和最后一天(除了每一个月份和最后一个月份),不一定是记录的最小日期和最大日期。
不明白你的解释,我不认为这点有问题(在where条件中已经限定)。

2、而且起止时间若是跨年度时,结果也会不正确,可以试试从‘2000-9-10’到‘2001-10-15’,你的语句会将两年的9月份数据加在一起。
这是我的疏忽,应该改为:
ORACLE:
select min(mydate) || '至' || max(mydate), sum(mycount)
from mytable
where mydate between to_date('2000-09-3','yyyy-mm-dd')
and to_date('2000-12-17','yyyy-mm-dd')
group by to_char(mydate, 'YYYYMM');

ACCESS:
select min(mydate) & "至" & max(mydate), sum(mycount)
from mytable
where mydate between #2000-9-3# and #2000-12-17#
group by year(mydate), month(mydate)
  • 打赏
  • 举报
回复
KingSunSha 2001-09-19
To icevi(按钮工厂):
1、若是九月最多只有28 号的记录, 结果会是2000-9-01 至2000-9-28,与Orivan(椰子壳)要的结果可不一样。他要的是每月第一天和最后一天(除了每一个月份和最后一个月份),不一定是记录的最小日期和最大日期。
不明白你的解释,我不认为这点有问题(在where条件中已经限定)。

2、而且起止时间若是跨年度时,结果也会不正确,可以试试从‘2000-9-10’到‘2001-10-15’,你的语句会将两年的9月份数据加在一起。
这是我的疏忽,应该改为:
ORACLE:
select min(mydate) ¦¦ '至' ¦¦ max(mydate), sum(mycount)
from mytable
where mydate between to_date('2000-09-3','yyyy-mm-dd')
and to_date('2000-12-17','yyyy-mm-dd')
group by to_char(mydate, 'YYYYMM');

ACCESS:
select min(mydate) & "至" & max(mydate), sum(mycount)
from mytable
where mydate between #2000-9-3# and #2000-12-17#
group by year(mydate), month(mydate)
  • 打赏
  • 举报
回复
icevi 2001-09-19
KingSunSha(弱水三千) :
若是九月最多只有28 号的记录, 结果会是
2000-9-01 至2000-9-28
与Orivan(椰子壳)要的结果可不一样。他要的是每月第一天和最后一天(除了每一个月份和最后一个月份),不一定是记录的最小日期和最大日期。

而且起止时间若是跨年度时,结果也会不正确,可以试试从‘2000-9-10’到‘2001-10-15’,你的语句会将两年的9月份数据加在一起。

我觉得这样写:(sql server 7.0/2000)

select convert( varchar,(case fyear*12+fmonth when year('2000-9-3')*12+month('2000-9-3')
then min(fdate)
else dateadd(day,-day(min(fdate)),min(fdate))+1 end),111) +' 至 '+

convert(varchar,(case fyear*12+fmonth when year('2001-12-17')*12+month('2001-12-17')
then max(fdate)
else dateadd(month,1,dateadd(day,-day(max(fdate)),max(fdate))+1)-1 end ),111)
AS Fperiod,sum(fcount) as fsumcount
from
(
select fdate,fcount,year(fdate ) as fyear,month(fdate) as fmonth
from mytable
) t1
where t1.fdate between '2000-9-3' and '2001-12-17'
group by fyear,fmonth
  • 打赏
  • 举报
回复
icevi 2001-09-19
KingSunSha(弱水三千) :
若是九月最多只有28 号的记录, 结果会是
2000-9-01 至2000-9-28
与Orivan(椰子壳)要的结果可不一样。起止日期是当月第一天或最后一天,而不是已发生的最小日期或最大日期。

而且起止时间若是跨年度时,结果也会不正确,可以试试从‘2000-9-10’到‘2001-10-15’,这条语句会将两年的9月份数据加在一起。

我觉得这样写:(sql server 7.0/2000)

select convert( varchar,(case fyear*12+fmonth when year('2000-9-3')*12+month('2000-9-3')
then min(fdate)
else dateadd(day,-day(min(fdate)),min(fdate))+1 end),111) +' 至 '+

convert(varchar,(case fyear*12+fmonth when year('2001-12-17')*12+month('2001-12-17')
then max(fdate)
else dateadd(month,1,dateadd(day,-day(max(fdate)),max(fdate))+1)-1 end ),111)
AS Fperiod,sum(fcount) as fsumcount
from
(
select fdate,fcount,year(fdate ) as fyear,month(fdate) as fmonth
from mytable
) t1
where t1.fdate between '2000-9-3' and '2001-12-17'
group by fyear,fmonth

Orivan(椰子壳) : 你的字段名是date 和count ,我改成了fdate和fcount

  • 打赏
  • 举报
回复
icevi 2001-09-19
KingSunSha(弱水三千) :
若是九月最多只有28 号的记录, 结果会是
2000-9-01 至2000-9-28
与Orivan(椰子壳)要的结果可不一样。Orivan(椰子壳)的每行中开始日期是1 号,而不是最小日期,结束日期是最后一天,而不是最大日期。

而且起止日期若是跨年度时,结果也会不正确,可以试试从‘2000-9-10’到‘2001-10-15’,这条语句会将两年的9月份数据加在一起。

我觉得这样写: (sql server 7。0/2000)
select convert( varchar,(case fyear*12+fmonth when year('2000-9-30')*12+month('2000-9-30')
then min(date)
else dateadd(day,-day(min(date)),min(date))+1 end),111) +' 至 '+

convert(varchar,(case fyear*12+fmonth when year('2000-12-17')*12+month('2000-12-17')
then max(date)
else dateadd(month,1,dateadd(day,-day(max(date)),max(date))+1)-1 end ),111)
AS Fperiod,sum(count) as fsumcount
from
(
select date,count,year(date ) as fyear,month(date) as fmonth
from mytable
) t1
where t1.date between '2000-9-30' and '2000-12-17'
group by fyear,fmonth
  • 打赏
  • 举报
回复
smartdonkey 2001-09-19
create table test(id int,date datetime,count int)
go
select distinct d=convert(char(10),(select min(date) from test where month(date)=t1.month),20)+'到'+
convert(char(10),(select max(date) from test where month(date)=t1.month),20),t1.count from test ,
(select month=month(date),count=count(*) from test t1 group by month(date)) t1
  • 打赏
  • 举报
回复
smartdonkey 2001-09-19
另外这种区间查询,最好在mydate上建立聚簇索引
  • 打赏
  • 举报
回复
Mr.Osc 2001-09-18
我去试试,如果成功一定加分!
  • 打赏
  • 举报
回复
KingSunSha 2001-09-18
如果你的分段标准是以月来算的话,那还不是很难
ORACLE:
select min(mydate) || '至' || max(mydate), sum(mycount)
from mytable
where mydate between to_date('2000-09-30','yyyy-mm-dd')
and to_date('2000-12-17','yyyy-mm-dd')
group by to_char(mydate, 'MM');

ACCESS:
select min(mydate) & "至" & max(mydate), sum(mycount)
from mytable
where mydate between #2000-9-30# and #2000-12-17#
group by month(mydate)
  • 打赏
  • 举报
回复
寒星 2001-09-18
我也来学习学习。
  • 打赏
  • 举报
回复
发帖
MS-SQL Server
加入

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
申请成为版主
帖子事件
创建了帖子
2001-09-18 09:52
社区公告
暂无公告