请教非自然月的统计
有个表,假设只有三个字段:ID(自动增长)、日期、金额。
现在要分年统计每年1-12月的金额总数,但是月份不是按自然月来计算,而是上月的26日至本月的25日为一个计费月。比如说8月份为7月26日至8月的25日。这里还涉及到了跨年度的问题,比如说2012年1月份的统计范围实际上是2011年12月26日至2012年1月25日。
现在要生成如下报表,请问应该怎样写这个存储过程?谢谢!
[解决办法]
--试下,应没错
select datepart(year,dateadd(day,-25,日期)),
sum(case when datepart(month,dateadd(day,-25,日期))=1 then 金额 else 0 end) [1月],
sum(case when datepart(month,dateadd(day,-25,日期))=2 then 金额 else 0 end) [2月],
sum(case when datepart(month,dateadd(day,-25,日期))=3 then 金额 else 0 end) [3月],
sum(case when datepart(month,dateadd(day,-25,日期))=4 then 金额 else 0 end) [4月],
sum(case when datepart(month,dateadd(day,-25,日期))=5 then 金额 else 0 end) [5月],
sum(case when datepart(month,dateadd(day,-25,日期))=6 then 金额 else 0 end) [6月],
sum(case when datepart(month,dateadd(day,-25,日期))=7 then 金额 else 0 end) [7月],
sum(case when datepart(month,dateadd(day,-25,日期))=8 then 金额 else 0 end) [8月],
sum(case when datepart(month,dateadd(day,-25,日期))=9 then 金额 else 0 end) [9月],
sum(case when datepart(month,dateadd(day,-25,日期))=10 then 金额 else 0 end) [10月],
sum(case when datepart(month,dateadd(day,-25,日期))=11 then 金额 else 0 end) [11月],
sum(case when datepart(month,dateadd(day,-25,日期))=12 then 金额 else 0 end) [12月]
from 你的表
where datepart(year,dateadd(day,-25,日期)) between 2008 and 2012
group by datepart(year,dateadd(day,-25,日期))
select year(日期) AS 年,
sum(case when MONTH(日期+7)=1 then 1 ELSE 0 END) as [1月],
sum(case when convert(VARCHAR(5),日期,10) between '01-25' and '02-26'then 金额 else 0 end) as [2月],
sum(case when convert(VARCHAR(5),日期,10) between '02-25' and '03-26'then 金额 else 0 end) as [3月],
sum(case when convert(VARCHAR(5),日期,10) between '03-25' and '04-26'then 金额 else 0 end) as [4月],
sum(case when convert(VARCHAR(5),日期,10) between '04-25' and '05-26'then 金额 else 0 end) as [5月],
sum(case when convert(VARCHAR(5),日期,10) between '05-25' and '06-26'then 金额 else 0 end) AS [6月],
sum(case when convert(VARCHAR(5),日期,10) between '06-25' and '07-26'then 金额 else 0 end) as [7月],
sum(case when convert(VARCHAR(5),日期,10) between '07-25' and '08-26'then 金额 else 0 end) as [8月],
sum(case when convert(VARCHAR(5),日期,10) between '08-25' and '09-26'then 金额 else 0 end) as [9月],
sum(case when convert(VARCHAR(5),日期,10) between '09-25' and '10-26'then 金额 else 0 end) as [10月],
sum(case when convert(VARCHAR(5),日期,10) between '10-25' and '11-26'then 金额 else 0 end) as [11月],
sum(case when convert(VARCHAR(5),日期,10) between '11-25' and '12-26'then 金额 else 0 end) as [12月]
FROM [tb]
GROUP BY year(日期)
when DATEPART(DD,日期)>=26 then (DATEPART(MM,日期)+1)%12
else DATEPART(MM,日期)
end 月份,
case
when DATEPART(DD,日期)>=26 and DATEPART(MM,日期)=12 then (DATEPART(YY,日期)+1)
else DATEPART(YY,日期)
end 年份,
金额
from 表名
) src
pivot(sum(金额) for 月份 in([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]))T1
)T2
[解决办法]
;with CET1 AS
(select left(cast(value as varchar(6)),4) as 年份,right(cast(value as varchar(6)),2) as 月份, freight as 金额
from Orders a, dbo.fn_DayList('19900101','20200101')
where orderdate > = StartT and orderdate < EndT and Type = '月')
select 年份,[01] as [1月],[02] as [2月],[03] as [3月],[04] as [4月],[05] as [5月],[06] as [6月],
[07] as [7月],[08] as [8月],[09] as [9月],[10] as [10月],[11] as [11月],[12] as [12月]
from CET1 pivot(sum(金额) for 月份 in ([01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],[12]))p
/*
年份 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
-- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------------
1996 NULL NULL NULL NULL NULL NULL 983.02 1423.67 1197.54 1351.24 2275.66 2552.20
1997 2110.53 1889.41 1886.87 3110.39 3025.46 2283.24 1941.82 3370.66 3057.88 4076.59 2206.23 3137.98
1998 5208.76 4531.13 3981.22 7815.67 1525.52 NULL NULL NULL NULL NULL NULL NULL
(3 行受影响)
关于 dbo.fn_DayList 的用法,可参阅我的CSDN博客 自定义时间序列 的内容
示例数据取自SQL SERVER 2005 示例数据库Northwind 的 Orders 表
*/