【问题标题】:Need to calculate the average of cost based on a per fiscal week basis需要根据每个会计周计算平均成本
【发布时间】:2014-02-06 10:53:20
【问题描述】:

我希望有人可以帮助解决我遇到的这个问题,我正在尝试从以下数据示例中计算出每周平均值:

    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 多个,而不仅仅是上面的那些),然后每周计算出来,例如在第 1 周将没有平均值,但第 2 周将是第 1 周和第 2 周的平均值,然后第 3 周将是第 1、2 和 3 周的平均值,依此类推。然后,我需要通过练习 ID 和每个会计周显示此信息。

目前我有一些不漂亮的代码,必须有一个更简单的方法,这段代码是:

我将所有数据传递到一个表变量中,然后使用 CTE 我使用案例语句来设置每个单独的星期,例如:

  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,但没有看到一种简单的方法。

【问题讨论】:

  • 我希望所有问题都得到很好的解释和精美的格式!
  • 你是说你想运行 avg() 吗?

标签: sql sum average


【解决方案1】:

您正在寻找平均值的累积平均值。在支持窗口/分析函数的数据库中,您可以:

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;

一个人将每周视为最终平均值中的一个数据点(您似乎想要的)。其他每周按一周中的点数加权(后一种解决方案)。当周数不同时,这些可能会产生非常不同的结果。

【讨论】:

    【解决方案2】:

    我不知道我是否完全理解这个问题:但是尝试执行这个:应该可以帮助你:

    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;
    

    【讨论】:

    • 谢谢,这几乎可以满足我的需求,我现在唯一需要做的事情是,我不确定如何为缺失的几周创建一些虚拟条目,这些条目来自桌子。基本上,如果有第 1、2、3、7、9、10 周的条目,我怎样才能以零成本获得缺少的第 4、5、6、8 周?如果这是有道理的。
    【解决方案3】:

    我认为这可行:

    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 周),那么您必须找到所有周数中的最小值。

    此外,如果您要跨多年计算,这将不起作用,但我认为情况并非如此。

    【讨论】:

    • 我确实需要添加的一件事是我需要考虑一个财政周没有条目的情况,例如,一个练习可能需要第 1、2、3 和 4 周的成本,但是第 5 周什么都没有,然后继续 6、7、8 等。然后我需要计算 8 周而不是 7 周的平均值,即使这意味着从技术上讲第 5 周为零。我已经使用了上面的代码,因为我使用的是表变量,我被告知我需要将表声明为变量,即使它是,如果我使用与 t 相同的别名,那么每次练习的平均值相同每周。
    • 我已经更新了答案,以考虑没有条目的财政周。我不明白您对表格的问题,但我在代码中添加了另一个别名 - 看看它是否有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    相关资源
    最近更新 更多