【问题标题】:Working out a rolling average where you don't always divide by the total count计算出一个滚动平均值,您并不总是除以总数
【发布时间】:2020-08-03 10:08:52
【问题描述】:

我正在尝试计算板球击球手的滚动平均值。任何了解这项运动的人都会知道,平均值是按得分/局数计算的,除非击球手没有出局。如果击球手打了 2 局,并且其中 1 局“未出局”,则他们的平均数将计算为

runs scored innings 1 + runs scored innings 2 / 1

如果他们在两局中都出局,则计算为

runs scored innings 1 + runs scored innings 2 / 2

这很容易计算总体平均值,但我想将其计算为运行平均值。在使用循环并单独计算每行的平均值之前,我已经这样做了,但是任何人都可以建议一种使用任何内置函数的方法吗?

当前代码示例:

with cte as (
select 
Innings_Player, 
Innings_Runs_Scored, 
Innings_Date, 
CASE WHEN Innings_Runs_Scored = "DNB" THEN null WHEN Innings_Runs_Scored LIKE "%*%" THEN REPLACE(Innings_Runs_Scored,"*","") ELSE Innings_Runs_Scored END AS RunsNum,
CASE WHEN Innings_Runs_Scored LIKE "%*%" THEN 1 ELSE 0 END AS NotOutFlag,
ROW_NUMBER() OVER (PARTITION BY Innings_Player ORDER BY Innings_Date) as RN
from TABLE
where Innings_Player = "JE Root"
AND Innings_Runs_Scored IS NOT NULL
ORDER BY Innings_Date
)
,cte2 as
(
select
 *,
   SUM(CAST(RunsNum AS INT64)) OVER (PARTITION BY Innings_Player ORDER BY RN) AS RunningTotal,
   AVG(CAST(RunsNum AS INT64)) OVER (PARTITION BY Innings_Player ORDER BY RN) AS RunningAvg,
 from cte
 where runsNum IS NOT NULL AND runsNum <> "TDNB"
)

select * from cte2

结果数据集:

因此,平均值不正确。对于滚动平均值,第三行的计算应该是前三行的 innings_run_scored,除以 2 而不是 3,正如您从 NotOutFlag 中看到的那样,列表中的 3 局未出局。

类似地,第 4 行应该除以 3,第 5 行除以 4,然后由于第 6 行也没有出现,第 6 行应该除以 4,第 7 行除以 5 等等。我认为等式会是

Innings_Run_Scored / Innings - Not Out Count

【问题讨论】:

  • 示例输入数据和预期输出将对您的问题有很大帮助。
  • 嗨,蒂姆,有一张数据看起来像的屏幕截图,然后在它下面解释了它应该是什么。干杯,加雷斯。
  • @gsweet87 。 . .您的问题和您的数据并不完全一致。查询比问题有更多的逻辑,这使得甚至很难开始。
  • 嗨,戈登,查询显示了我如何计算当前滚动平均值,但问题是我如何计算滚动平均值,但将“NotOutFlag”从用于计算平均值的计数中取出。我不认为我解释得很好,因为它很复杂。您能否详细说明一下混乱的确切位置,然后我可以编辑问题?
  • @gsweet87 。 . .蒂姆已经解释过了。显示样本数据。显示您想要的结果。根据您提供的数据解释您要实现的逻辑。

标签: sql google-bigquery average


【解决方案1】:

AVG 基本上是SUM / COUNT 因为你想改变COUNT 部分我建议放弃使用AVG 功能。您可以使用SUMCASE 来计算NotOutFlag0 的情况

这样行

   AVG(CAST(RunsNum AS INT64)) OVER (PARTITION BY Innings_Player ORDER BY RN) AS RunningAvg,

会变成

   SUM(CAST(RunsNum AS INT64)) OVER (PARTITION BY Innings_Player ORDER BY RN) 
/  SUM(CASE WHEN NotOutFlag = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY Innings_Player ORDER BY RN)
AS RunningAvg,

当然,您需要添加更多逻辑以避免除以 0。

CASE WHEN SUM(CASE WHEN NotOutFlag = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY Innings_Player ORDER BY RN) = 0 
THEN 0 
ELSE 
SUM(CAST(RunsNum AS INT64)) OVER (PARTITION BY Innings_Player ORDER BY RN) 
/  
SUM(CASE WHEN NotOutFlag = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY Innings_Player ORDER BY RN) 
END  AS RunningAvg,

【讨论】:

  • 谢谢加布里埃尔,今晚我会玩这个。
猜你喜欢
  • 1970-01-01
  • 2013-02-25
  • 2016-11-14
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多