我希望有人可以帮我解决这个问题,我试图通过以下数据示例计算每周平均值:
Practice ID Cost FiscalWeek
1 10.00 1
1 33.00 2
1 55.00 3
1 18.00 4
1 36.00 5
1 24.00 6
13 56.00 1
13 10.00 2
13 24.00 3
13 30.00 4
13 20.00 5
13 18.00 6
我想要的是按练习ID进行分组,但是计算出每个练习的平均值(这些练习中有超过500个不仅仅是上面的练习ID),并且每周都要练习一次,所以例如在第1周就没有了平均值,但第2周将是第1周和第2周的平均值,然后第3周将是第1,2周和第3周的平均值,然后是第2周。然后我需要通过练习ID和每个财政周来证明这一点。
目前我有一些不漂亮的代码,并且必须有一个更简单的方法,这段代码是:
我将所有数据传递给表变量然后使用CTE然后使用case语句来设置每个星期,如:
CASE WHEN fiscalweek = 1 THEN cost ELSE 0 END AS [1],
CASE WHEN fiscalweek = 2 THEN cost ELSE 0 END AS [2],
CASE WHEN fiscalweek = 3 THEN cost ELSE 0 END AS [3]
这会将第1周的成本带回到它自己的专栏中,例如1,2,3等等,然后我用了第二个CTE来计算每周的列数,所以例如计算出第6周我将使用这个代码:
sum([1]) as 'Average Wk 1',
sum([1]+[2])/2 as 'Average Wk 2',
sum([1]+[2]+[3])/3 as 'Average Wk 3',
sum([1]+[2]+[3]+[4])/4 as 'Average Wk 4',
sum([1]+[2]+[3]+[4]+[5])/5 as 'Average Wk 5'
sum([1]+[2]+[3]+[4]+[5]+[6])/6 as 'Average Wk 6'
我已经考虑过在T-SQL中准确计算出这个平均值的各种不同方法,所以我最终可以将它放到SSRS中。我已经考虑过使用While..Loop,Cursor,但没有看到一个简单的方法。
答案 0 :(得分:2)
您正在寻找平均值的累积平均值。在支持窗口/分析功能的数据库中,您可以执行以下操作:
select fiscalweek, avg(cost) as avgcost,
avg(avg(cost)) over (order by fiscalweek) as cumavg
from practices p
group by fiscalweek
order by 1;
如果你没有窗口函数,那么你需要使用某种形式的相关子查询或加入:
select p1.fiscalweek, avg(p1.avgcost)
from (select fiscalweek avg(cost) as avgcost
from practices p
group by fiscalweek
) p1 join
(select fiscalweek avg(cost) as avgcost
from practices p
group by fiscalweek
) p2
on p12 <= p1
group by p1.fiscalweek
order by 1;
我想提醒您,您正在计算“平均值”。这与累积平均值不同,累计平均值可以计算为:
select fiscalweek,
(sum(sum(cost)) over (order by fiscalweek) /
sum(count(*)) over (order by fiscalweek)
) avgcost
from practices p
group by fiscalweek
order by 1;
每周将一个视为最终平均值中的一个数据点(您似乎想要的)。每周其他权重乘以一周内的点数(后一种解决方案)。当数周的点数不同时,这些结果会产生非常不同的结果。
答案 1 :(得分:0)
我认为这样可行:
SELECT t1.pid,
t1.fiscalweek,
(
SELECT SUM(t.cost)/COUNT(t.cost)
FROM tablename AS t
WHERE t.pid = t1.pid
AND t.fiscalweek <= t1.fiscalweek
) AS average
FROM tablename AS t1
GROUP BY t1.pid, t1.fiscalweek
修改
要考虑没有参赛作品的财政周,您可以简单地交换
SELECT SUM(t.cost)/COUNT(t.cost)
的
SELECT SUM(t.cost)/t1.fiscalweek
从第1周或
计算SELECT SUM(t.cost)/(t1.fiscalweek - MIN(t.fiscalweek) + 1)
从这种做法的第一周开始计算。
如果所有练习平均值应该在同一周开始(而不一定是第1周),那么你必须找到所有周数的最小值。
此外,如果您计算多年,这将无效,但我认为这不是他的情况。
答案 2 :(得分:0)
我不知道如果我完全理解这个问题:但尝试执行此操作:应该帮助您:
create table #practice(PID int,cost decimal,Fweek int)
insert into #practice values (1,10,1)
insert into #practice values (1,33,2)
insert into #practice values (1,55,3)
insert into #practice values (1,18,4)
insert into #practice values (1,36,5)
insert into #practice values (1,24,6)
insert into #practice values (13,56,1)
insert into #practice values (13,10,2)
insert into #practice values (13,24,3)
insert into #practice values (13,30,4)
insert into #practice values (13,20,5)
insert into #practice values (13,18,6)
select * from #practice
select pid,Cost,
(select AVG(cost) from #practice p2 where p2.Fweek <= p1.Fweek and p1.pid = p2.pid) WeeklyAVG,
Fweek,AVG(COST) over (Partition by PID) as PIDAVG
from #practice p1;