不存在值时的oracle sql运行平均值(隐含0)

zfciruhq  于 2023-03-01  发布在  Oracle
关注(0)|答案(2)|浏览(135)

我正试图做一个移动平均报告,但遇到了一个障碍:
选择某个时间段的数据时,报表中的某些组将没有该时间段的数据,这意味着值为0
因此,我运行下面的查询:

SELECT CY_WEEK,
       RC,
       SUM(DURATION_MINUTES) OVER (ORDER BY CY_WEEK ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS rolling_avg
FROM MI_REPORT where CY_WEEK in ('2022_08','2022_09','2022_10','2022_11') and RC = 'FOO';

它产生:

2022_11,FOO,97

正如我们在选择本例的数据时所看到的,实际上只有1个条目

select CY_WEEK, RC,DURATION_MINUTES from MI_REPORT where CY_WEEK in ('2022_08','2022_09','2022_10','2022_11') and RC = 'FOO'

它产生的结果与平均值相同:

2022_11,SCM,97

但平均值实际上需要为97/4 = 24.25
我怎样才能做到这一点,而不捏造一堆回来的数据?

brccelvz

brccelvz1#

这听起来就像你得到了你的总和,你只是除以4。你确实需要一个Coalesce(calulation,0)把null变成0。

Coalesce(SUM(DURATION_MINUTES) OVER (ORDER BY CY_WEEK ROWS BETWEEN 3 PRECEDING AND CURRENT ROW),0)/4
ni65a41a

ni65a41a2#

如果您需要一个移动平均值,则应使用AVG,而不是SUM:

SELECT CY_WEEK,
       RC,
       AVG(DURATION_MINUTES) OVER (ORDER BY CY_WEEK ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS rolling_avg
FROM MI_REPORT where CY_WEEK in ('2022_08','2022_09','2022_10','2022_11') and RC = 'FOO';

请记住,如果您将行限制为仅4周,并且有4周的窗口,则实际上并没有运行平均值,因为只有最后一行的平均值中包含整整4个期间。您可能需要删除 predicate ,并允许更长的时间段来查看真正的运行平均值。

SELECT CY_WEEK,
       RC,
       AVG(DURATION_MINUTES) OVER (ORDER BY CY_WEEK ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS rolling_avg
  FROM MI_REPORT where RC = 'FOO';

如果您只想查看特定四周的结果,请在外部查询块中应用该 predicate (* 在 * 计算运行平均值之后):

SELECT CY_WEEK,
       RC,
       rolling_avg
 FROM (SELECT CY_WEEK,
              RC,
              AVG(DURATION_MINUTES) OVER (ORDER BY CY_WEEK ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS rolling_avg
         FROM MI_REPORT where RC = 'FOO')
where CY_WEEK in ('2022_08','2022_09','2022_10','2022_11')

相关问题