【问题标题】:Moving (Rolling) Median with BigQuery使用 BigQuery 移动(滚动)中位数
【发布时间】:2019-05-24 09:56:37
【问题描述】:

我目前在 BigQuery 中有一个包含一些异常值的表,我想计算该表的移动中位数。

示例表:

port - qty - datetime
--------------------------------
TCP1 - 13 - 2018/06/11 11:20:23
UDP2 - 15 - 2018/06/11 11:24:24
TCP3 - 12 - 2018/06/11 11:24:27
TCP1 - 2  - 2018/06/12 11:24:26 
UDP2 - 15 - 2018/06/12 11:35:32
TCP3 - 200- 2018/06/13 11:45:23
TCP3 - 14 - 2018/06/13 11:54:22
TCP3 - 13 - 2018/06/14 11:55:33
TCP1 - 17 - 2018/06/15 11:43:33
UDP2 - 12 - 2018/06/15 11:55:25
TCP3 - 14 - 2018/06/15 11:26:21
TCP3 - 11 - 2018/06/16 11:55:46
TCP1 - 14 - 2018/06/17 11:34:33
UDP2 - 15 - 2018/06/17 11:43:24
TCP3 - 13 - 2018/06/17 11:47:54
and ...

我希望能够使用 bigquery 标准 SQL 在 11 小时计算各个端口的 7 天移动中位数。 我已经尝试计算移动平均线,但已经意识到计算受到“异常值”的影响。

我不知道如何编写 SQL 查询来计算移动中位数。任何帮助将不胜感激。

(这是我在这个主题上能找到的最接近的线程:BigQuery - Moving median calculation,但我需要 bigquery 才能从表中获取数量,因为我不知道每个特定日期的确切数量)

【问题讨论】:

  • 太宽泛 - 您可能希望根据问题中的输入示例呈现预期结果

标签: sql google-bigquery median bigquery-standard-sql


【解决方案1】:

我认为这已经足够接近你想要的了:

select t.*,
       qtys[ordinal(cast(array_length(qtys) / 2 as int64))]
from (select t.*,
             array_agg(qty) over (partition by port
                                  order by datetime_diff(datetime, datetime('2000-01-01'), day)
                                  range between 7 preceding and current day
                                 ) as qtys
      from t
      where extract(hour from datetime) = 11
     ) t;

当结果集中有偶数行时,中位数有点棘手。这会选择一个任意值。

【讨论】:

  • 嗨,想问一下“order by datetime_diff(datetime, datetime('2000-01-01'), day) range between 7 before and current day”是什么意思??是否会影响 1 个月前的移动中位数的计算?
  • @taN 。 . . array_agg() 不支持日期/日期时间/时间戳上的窗口 range 子句。但它确实支持数字上的窗口 range 子句。所以这会将日期转换为数字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多