从旧版SQL迁移:" WITHIN RECORD"的选项使用标准SQL

时间:2017-10-10 18:04:46

标签: google-bigquery

我正在尝试从BigQuery Legacy SQL迁移到标准SQL。 Legacy产品提供了查询" WITHIN RECORD"它在很多场合都派上用场了。

我正在寻找一种有效的替代WITHIN RECORD。我总是可以使用几个子查询并加入它们,但想知道是否有更有效的方法使用ARRAY + ORDINAL。

示例:请考虑以下标准SQL

WITH
  sessPageVideoPlays AS (
    SELECT fullVisitorId, visitNumber, h.page.pagePath,
        # This would previously use WITHIN RECORD in Legacy SQL:
        ARRAY( SELECT eventInfo.eventAction FROM UNNEST(hits)
               WHERE eventInfo.eventCategory="videoPlay" 
               ORDER BY hitNumber DESC
        )[ORDINAL(1)] AS lastVideoSeen
    FROM
          `proj.ga_sessions`, UNNEST(hits) as h
    GROUP BY fullVisitorId, visitNumber, h.page.pagePath, lastVideoSeen
  )
SELECT 
  pagePath, lastVideoSeen, numOccur  
FROM 
     (SELECT    
        pagePath, lastVideoSeen, count(1) numOccur
      FROM
        sessPageVideoPlays
      GROUP BY
        pagePath, lastVideoSeen
)

产生的结果:

Table 1

问题:

1)我想在给定的页面上看到最后一个视频播放事件,这是我使用WITHIN RECORD完成的但是我正在尝试上面显示的ARRAY + ORDINAL方法。但是为了实现这一点,我认为ARRAY()中的SELECT语句必须同步到外部记录,因为它现在已经被展平了?那是准确的吗?

2)我还希望获得在给定页面上播放的COUNT个DISTINCT视频,并想知道更有效的方法是加入单独的查询还是插入另一个内联聚合函数,就像上面的ARRAY一样。

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:2)

  

1)我想在给定页面上看到最后一个视频播放事件,   这是我使用WITHIN RECORD完成的但是我正在尝试   上面显示的ARRAY + ORDINAL方法。但是为了这个工作,   我认为ARRAY()中的SELECT语句必须同步   自从它现在变平以来的外部记录?那是准确的吗?

我认为这是正确的。使用您的查询,内部查询中的UNNEST(命中)将独立于外部UNNEST,并且可能不希望您想要。

我想也许有一种方法可以写出来:

WITH
  sessPageVideoPlays AS (
    SELECT fullVisitorId, visitNumber,
        ARRAY(
          SELECT AS STRUCT pagePath, lastVideoSeen FROM (
            SELECT
              page.pagePath,
              eventInfo.eventAction AS lastVideoSeen,
              ROW_NUMBER() OVER (PARTITION BY page.pagePath ORDER BY hitNumber DESC) AS rank
            FROM UNNEST(hits)
            WHERE eventInfo.eventCategory="videoPlay")
          WHERE rank = 1
        ) AS lastVideoSeenOnPage
    FROM
      `proj.ga_sessions`
  )
SELECT 
  pagePath, lastVideoSeen, numOccur  
FROM (
  SELECT
    pagePath, lastVideoSeen, count(1) numOccur
  FROM
    sessPageVideoPlays, UNNEST(lastVideoSeenOnPage)
  GROUP BY
    pagePath, lastVideoSeen
)
  

2)我还想获得一个给定的COUNT个DISTINCT视频   页面,并想知道更有效的方法是否会加入到   单独查询或插入另一个内联聚合函数,如   完成上面的ARRAY。

我认为两者都可以,但是插入另一个内联聚合函数会将它们评估得更近,所以如果有机会,查询引擎可能会更容易优化。