BigQuery 或 SQL 中的增量方法?

Posted

技术标签:

【中文标题】BigQuery 或 SQL 中的增量方法?【英文标题】:Delta Method In BigQuery or SQL? 【发布时间】:2017-04-28 16:04:16 【问题描述】:

因此,我试图构建一条 delta 曲线来观察 MLB 球员的表现如何随着年龄的增长而变化。

“delta 方法”着眼于所有连续几年参加比赛的球员。很明显,许多球员都有几个背靠背的“对联”。对于每个球员来说,它会计算他们在第一年和第二年的表现率之间的差异,并将该差异放入一个“桶”中,该桶由这两年中球员的年龄定义。

假设一名球员在 25 岁时的平均击球次数为 0.300,而在他 26 岁时的平均击球次数为 0.310。所以我们采用 +.10 的差值,并放入 25/26 岁“桶” ”。

所以我有一个这样构造的表:

ID   Name      Age  Average
123  Joe Smith  25  .300
123  Joe Smith  26  .310
123  Joe Smith  27  .312
123  Joe Smith  28  .315

所以我正在寻找的输出基本上是一个我正在创建一个新行的输出,该行标识所有实例,如果一个球员连续打赛季,我们看到平均差异(所以如果有人有一个年龄25 季但不是 26 岁的季节,它们不会被包括在内)。我确信这涉及某种 CASE 声明,但我对这一切有点生疏。如果您不了解 BigQuery,请随时回复,就像这是 SQL 一样。

【问题讨论】:

Mikhail 发布的答案的好处是它会导致单表扫描(因此是成本的一​​半)。 【参考方案1】:

试试下面的 BigQuery 标准 SQL

#standardSQL
SELECT ID, Name, Age, Average, bucket, ROUND(diff, 3) AS diff
FROM (
  SELECT *,
    CONCAT(CAST(Age AS STRING), '/', CAST(Age + 1 AS STRING)) AS bucket, 
    MAX(Average) OVER(nextYear) - Average AS diff
  FROM yourTable
  WINDOW nextYear AS (PARTITION BY ID ORDER BY Age RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
)
WHERE IFNULL(diff, 0) <> 0 
-- ORDER BY ID, Age  

您可以使用问题中的虚拟数据测试/玩它

#standardSQL
WITH yourTable AS (
  SELECT 123 AS ID, 'Joe Smith' AS Name, 25 AS Age, .300 AS Average UNION ALL
  SELECT 123, 'Joe Smith', 26, .310 UNION ALL
  SELECT 123, 'Joe Smith', 27, .312 UNION ALL
  SELECT 123, 'Joe Smith', 28, .315 
)
SELECT ID, Name, Age, Average, bucket, ROUND(diff, 3) AS diff
FROM (
  SELECT *,
    CONCAT(CAST(Age AS STRING), '/', CAST(Age + 1 AS STRING)) AS bucket, 
    MAX(Average) OVER(nextYear) - Average AS diff
  FROM yourTable
  WINDOW nextYear AS (PARTITION BY ID ORDER BY Age RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
)
WHERE IFNULL(diff, 0) <> 0 
ORDER BY ID, Age

【讨论】:

【参考方案2】:

在 sql 中,我会在 id 和 age+1=age 上进行自联接并计算差异:

select t1.id, t1.name, t1.age, t2.age, t1.average, t2.average, t2.average-t1.average as diff, concat(t1.age,'/',t2.age) as bucket
from yourtable t1
inner join yourtable t2
on t1.id=t2.id and t1.age+1=t2.age

内部连接将确保如果下一年没有完成的赛季,则该记录不包含在结果集中。

【讨论】:

有没有一种方法可以在不进行自连接的情况下完成?像某种形式的 CASE 语句之类的? 您可以使用analytic function,例如LAG. @ElliottBrossard mysql 没有 lag() 函数。它可以通过使用会话变量来模拟。 @RIPHarambe 通过使用会话变量可能是的,但是您需要一个子查询来删除您不需要的记录。带索引的自连接比这更有效。 @Shadow 我实际上能够让您的建议发挥作用。谢谢!

以上是关于BigQuery 或 SQL 中的增量方法?的主要内容,如果未能解决你的问题,请参考以下文章

Big Query 或 SQL 重塑数据

如何在 BIG QUERY 中仅选择增量记录

如何避免 BigQuery 中的 Power BI 增量刷新重复查询?

以增量方式将数据从 GCP Datastore 移动到 BigQuery 的最佳做法

在 SQL (Big Query) 中生成序列/范围/数组,其中最小值和最大值取自另一个表

如何重命名 Big Query 中的列? [关闭]