我有以下不同的年份数据:
yearmonth value1
--------- ------
2016/01 33
2016/02 22
2016/03 22
2016/04 22
2016/05 22
2016/06 25
2016/07 44
2016/08 44
2016/09 44
2016/10 66
2016/11 44
2016/12 34
我想计算每季度value1
的平均值。
考虑如下:
Quarter 1 = month 01 till month 03
Quarter 2 = month 01 till month 06
Quarter 3 = month 01 till month 09
Quarter 4 = month 01 till month 12
我尝试使用over,但未获取正确的数据。
答案 0 :(得分:0)
drop table tab1;
create table tab1 (
yearmonth char(7),
val number
);
insert into tab1 values('2016/02', 12);
insert into tab1 values('2017/09', 10);
insert into tab1 values('2018/11', 8);
insert into tab1 values('2013/07', 6);
insert into tab1 values('2014/12', 5);
insert into tab1 values('2016/08', 25);
insert into tab1 values('2013/06', 6);
insert into tab1 values('2013/04', 6);
--version 1
select q, round(avg(val),4) as avg_val
from (
select a.*,
to_char(to_date(yearmonth, 'yyyy/MM'),'Q') as Q -- convert string to date and get Q
from tab1 a
)
group by q
order by q
-- version 2
select
avg(case when q <= 1 then val end) as q1_cum,
avg(case when q <= 2 then val end) as q2_cum,
avg(case when q <= 3 then val end) as q3_cum,
avg(case when q <= 4 then val end) as q4_cum
from (
select a.*,
to_number(to_char(to_date(yearmonth, 'yyyy/MM'),'Q')) as q -- convert string to date and get Q
from tab1 a
) a
答案 1 :(得分:0)
在SQL Server 2008中:
我做了四分之一的时间,您可以尝试类似的方法:
create table calculation
(
yearmonth varchar(200),
value1 float
);
insert into calculation values('2016/01',33);
insert into calculation values('2016/02',22);
insert into calculation values('2016/03',22);
insert into calculation values('2016/04',22);
insert into calculation values('2016/05',22);
insert into calculation values('2016/06',25);
select
avg(case when yearmonth between '2016/01' and '2016/03' then value1 end) as qtr1
from calculation
注意: 以正确的格式存储日期
答案 2 :(得分:0)
我附上了SQL Server版本-上一个是Oracle版本::)
create table tab1 (
yearmonth varchar(7),
val int
);
insert into tab1 values('2016/02', 12);
insert into tab1 values('2017/09', 10);
insert into tab1 values('2018/11', 8);
insert into tab1 values('2013/07', 6);
insert into tab1 values('2014/12', 5);
insert into tab1 values('2016/08', 25);
insert into tab1 values('2013/06', 6);
insert into tab1 values('2013/04', 6);
select
avg(case when b.q <= 1 then val end) as q1_cum,
avg(case when b.q <= 2 then val end) as q2_cum,
avg(case when b.q <= 3 then val end) as q3_cum,
avg(case when b.q <= 4 then val end) as q4_cum
from (
select a.*,
datepart(quarter,convert(date,(yearmonth + '/01'),120)) as q
from tab1 a
) b
答案 3 :(得分:0)
尝试在列yearmonth
中添加一天,以便能够使用DATEPART
函数。
然后,您就有可能在季度的VALUE
之前获得平均PARTITIONs
:
SELECT
q.yearmonth
, q.QuarterPart
, AVG(q.val) OVER (PARTITION BY q.QuarterPart ORDER BY q.QuarterPart) AvgByQuarter
FROM
(
SELECT
t.yearmonth
, t.val
, DATEPART(QUARTER, concat(t.yearmonth, '/01')) QuarterPart
FROM @table t
)q
和示例数据:
DECLARE @table TABLE
(
yearmonth VARCHAR(10),
val int
);
insert into @table values('2016/01', 33);
insert into @table values('2016/02', 22);
insert into @table values('2016/03', 22);
insert into @table values('2016/04', 22);
insert into @table values('2016/05', 22);
insert into @table values('2016/06', 25);
insert into @table values('2016/07', 44);
insert into @table values('2016/08', 44);
insert into @table values('2016/09', 44);
insert into @table values('2016/10', 66);
insert into @table values('2016/11', 44);
insert into @table values('2016/12', 34);
输出:
yearmonth val QuarterPart AvgByQuarter
2016/01 33 1 25
2016/02 22 1 25
2016/03 22 1 25
2016/04 22 2 23
2016/05 22 2 23
2016/06 25 2 23
2016/07 44 3 44
2016/08 44 3 44
2016/09 44 3 44
2016/10 66 4 48
2016/11 44 4 48
2016/12 34 4 48
答案 4 :(得分:0)
有趣,您需要累积个季度。这使得这有些棘手。无论如何,我不会为此使用日期算法,因为源数据不是日期。
select q, avg(value1)
from t cross apply
(values ('q1'),
(case when right(yearmonth, 2) > '03' then 'q2' end),
(case when right(yearmonth, 2) > '06' then 'q3' end),
(case when right(yearmonth, 2) > '09' then 'q4' end)
) q
where q is not null
group by q;
实际上,我还将在left(yearmonth, 4)
和select
中都包含年份group by
。
如果您不想要累积结果,则:
select left(yearmonth, 4) as yyyy, q,
avg(value1)
from t cross apply
(values (case when right(yearmonth, 2) <= '03' then 'q1'
when right(yearmonth, 2) <= '06' then 'q2'
when right(yearmonth, 2) <= '09' then 'q3'
else 'q4'
end)
) q
where q is not null
group by eft(yearmonth, 4), q;
您也可以获取累计平均值:
select left(yearmonth, 4) as yyyy, q,
avg(value1),
(sum(sum(value1)) over (partition by left(yearmonth, 4) order by q) /
sum(count(*)) over (partition by left(yearmonth, 4) order by q)
) as cumulative_average