【问题标题】:BigQuery SQL Query OptimizationBigQuery SQL 查询优化
【发布时间】:2019-02-21 03:52:09
【问题描述】:

我设法得到一个有效的查询,但我很好奇是否有更简洁的方法来构造它(仍在学习!)。

我正在使用的 BigQuery 数据集来自 Hubspot。它由 Stitch 保持同步。 (对于那些不熟悉 BigQuery 的人,大多数集成都是仅附加的,因此我必须通过您将在下面看到的 ROW_NUMBER() OVER 行过滤掉旧副本,这就是它存在的原因。似乎是处理这个怪癖的标准方法。 )

companies 表的问题在于,除了两个 ID 字段外,每个字段都是 RECORD 类型。 (有关示例,请参见底部的屏幕截图)。它用于保存字段值更改的历史记录。不幸的是,它们似乎没有任何顺序,因此将字段(例如properties.first_conversion_event_name)包装在MIN()MAX() 中并且按companyid 公式分组不起作用。

这就是我最终得到的结果(最终查询要长得多;我没有包括下面示例中的所有字段):

WITH companies AS (
SELECT
    o.companyid as companyid,
    ARRAY_AGG(STRUCT(o.properties.name.value, o.properties.name.timestamp) ORDER BY o.properties.name.timestamp DESC)[SAFE_OFFSET(0)] as name,
    ARRAY_AGG(STRUCT(o.properties.industry.value, o.properties.industry.timestamp) ORDER BY o.properties.industry.timestamp DESC)[SAFE_OFFSET(0)] as industry,
    ARRAY_AGG(STRUCT(o.properties.lifecyclestage.value, o.properties.lifecyclestage.timestamp) ORDER BY o.properties.lifecyclestage.timestamp DESC)[SAFE_OFFSET(0)] as lifecyclestage
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY o.companyid ORDER BY o._sdc_batched_at DESC) as seqnum
  FROM `project.hubspot.companies` o) o
WHERE seqnum = 1
GROUP BY companyid)

SELECT
  companyid,
  name.value as name,
  industry.value as industry,
  lifecyclestage.value as lifecyclestage
FROM companies

顶部的WITH 子句是为了去掉ARRAY_AGG(STRUCT()) 包含的额外字段。对于每个字段,我将有两列 - [field].value[field].timestamp - 我只想要 [field].value 一个。

提前致谢!

Schema Screenshot

【问题讨论】:

    标签: sql optimization google-bigquery hubspot


    【解决方案1】:

    我设法得到一个有效的查询,但我很好奇是否有更简洁的方法来构造它(仍在学习!)。

    根据您提供的架构并假设您的查询确实返回了您所期望的 - 以下“优化”版本应该返回相同的结果

    #standardSQL
    WITH companies AS (
      SELECT
          o.companyid AS companyid,
          STRUCT(o.properties.name.value, o.properties.name.timestamp) AS name,
          STRUCT(o.properties.industry.value, o.properties.industry.timestamp) AS industry,
          STRUCT(o.properties.lifecyclestage.value, o.properties.lifecyclestage.timestamp) AS lifecyclestage
      FROM (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY o.companyid ORDER BY o._sdc_batched_at DESC) AS seqnum
        FROM `project.hubspot.companies` o
      ) o
      WHERE seqnum = 1
    )
    SELECT
      companyid,
      name.value AS name,
      industry.value AS industry,
      lifecyclestage.value AS lifecyclestage
    FROM companies   
    

    如您所见,我只是简单地删除了GROUP BY companyid,因为在您申请WHERE seqnum = 1 之后,每个 companyid 已经只有一个条目/行,所以根本没有理由将每个 companyid 分组为一行。出于同样的原因,我删除了ARRAY_AGG( ORDER BY)[SAFE_OFFSET(0)]——它只是聚合了一个结构,然后从数组中提取了一个元素——所以不需要这样做

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2014-02-04
      • 2014-11-16
      相关资源
      最近更新 更多