BigQuery:根据匹配数据和产品范围维度过滤匹配数据

时间:2018-12-23 15:13:04

标签: google-bigquery

在BigQuery中,有如下所述的基于Google Analytics(分析)的查询,此查询可以正常运行。

#standard sql   
SELECT
      Date,
      SUM(totals.visits) AS Sessions,
      SUM(totals.transactions) AS Transactions
    FROM
      `[projectID].[DatasetID].ga_sessions_*`
    WHERE
      _TABLE_SUFFIX BETWEEN '20181217'
      AND '20181217'
      AND totals.visits > 0
    GROUP BY
      Date

在此查询中,我需要排除匹配内 ...

内的所有匹配
  • .. GA自定义维度#23(匹配范围)包含值“编辑器” 或
  • .. GA自定义维度#6(乘积范围)匹配正则表达式值'^ 63 ..... $' 或
  • .. GA hits.page.pagePath匹配正则表达式值'gebak | cake'

注意:不是打算在会话级(如this screenshot)上应用上述3个条件,而是在命中级上使用,因为我想从另一个GA视图(而不是将数据加载到BigQuery的视图)中复制数字。在此其他GA视图中,将上述3个条件设置为视图过滤器。

到目前为止,“最佳”查询是以下查询(基于以下Martin Weitzmann的帖子)。但是,此查询未过滤数据集(换句话说,条件不起作用)。

SELECT Date, 
-- hits,
SUM(totals.transactions), 
SUM(totals.visits) 

FROM (

(
  SELECT date, totals,
    -- create own hits array
    ARRAY(
      SELECT AS STRUCT 
        hitnumber, 
        page,
        -- create own product array
        ARRAY(
          SELECT AS STRUCT productSku, productQuantity 
          FROM h.product AS p
          WHERE (SELECT COUNT(1)=0 FROM p.customDimensions WHERE index=6 AND value like '63%') 
        ) AS product
      FROM t.hits as h
      WHERE 
        NOT REGEXP_CONTAINS(page.pagePath,r'gebak|cake')
        AND
        (SELECT COUNT(1)=0 FROM h.customDimensions WHERE index=23 AND value like '%editor%')
    ) AS hits
  FROM
    `[projectID].[DatasetID].ga_sessions_*` t
  WHERE 
  _TABLE_SUFFIX BETWEEN '20181217'
  AND '20181217'
  AND totals.visits > 0
  ))
  GROUP BY Date

有人知道如何实现所需的输出吗?

非常感谢!

注意:由于隐私方面的考虑,两个查询中的projectID和datasetID都已被屏蔽。

2 个答案:

答案 0 :(得分:1)

只是一个简单的示例/想法,说明如何在公共场所使用WITH和REGEXP_EXTRACT

WITH CD6 AS (
SELECT cd.value, SUM(totals.visits) AS Sessions6Sum
FROM
  `bigquery-public-data.google_analytics_sample.ga_sessions_*`,
   UNNEST(hits) AS hits,
   UNNEST(hits.product) AS prod,
   UNNEST(prod.customDimensions) AS cd
   WHERE cd.index=6 
   AND NOT REGEXP_CONTAINS(cd.value,r'^63.....$')
   GROUP BY cd.value
),
CD23 AS (
SELECT cd.value, SUM(totals.visits) AS Sessions23Sum
FROM
  `bigquery-public-data.google_analytics_sample.ga_sessions_*`,
   UNNEST(hits) AS hits,
   UNNEST(hits.product) AS prod,
   UNNEST(prod.customDimensions) AS cd
   WHERE cd.index=23 
   AND NOT REGEXP_CONTAINS(cd.value,r'editor')
   GROUP BY cd.value
)

select CD6.Sessions6Sum + CD23.Sessions23Sum from CD6, CD23

您可以在bigQuery官方API page中获得有关如何使用REGEXP_EXTRACT的更多信息

答案 1 :(得分:1)

自己的数组逼近

您可以通过使用原始文件上的子查询并将其输出反馈到数组函数中来创建自己的匹配和产品数组。在这些子查询中,您可以过滤出匹配数据和产品:

#standardsql
SELECT
  date,
  hits
  --SUM(totals.visits) AS Sessions,
  --SUM(totals.transactions) AS Transactions
FROM
  (
  SELECT 
    date, totals,
    -- create own hits array
    ARRAY(
      SELECT AS STRUCT 
        hitnumber, 
        page,
        -- create own product array
        ARRAY(
          SELECT AS STRUCT productSku, productQuantity 
          FROM h.product AS p
          WHERE (SELECT COUNT(1)=0 FROM p.customDimensions WHERE index=6 AND value like '63%') 
        ) AS product
      FROM t.hits as h
      WHERE 
        NOT REGEXP_CONTAINS(page.pagePath,r'gebak|cake')
        AND
        (SELECT COUNT(1)=0 FROM h.customDimensions WHERE index=23 AND value like '%editor%')
    ) AS hits
  FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_20161104` t
  )
--GROUP BY 1
LIMIT 100

我将此示例保留为未分组状态,但是您可以通过注释掉hits并相应地分组来轻松地对其进行调整...

分段方法

我认为您只需要在WHERE语句中使用正确的子查询即可:

#standardsql
SELECT
  date,
  SUM(totals.visits) AS Sessions,
  SUM(totals.transactions) AS Transactions
FROM
  `bigquery-public-data.google_analytics_sample.ga_sessions_*` t
WHERE
  (SELECT COUNT(1)=0 FROM t.hits h
    WHERE 
      (SELECT count(1)>0 FROM h.customDimensions WHERE index=23 AND value like '%editor%')
      OR
      (SELECT count(1)>0 from h.product p, p.customdimensions cd WHERE index=6 AND value like '63%')
      OR
      REGEXP_CONTAINS(page.pagePath,r'gebak|cake')
  )
GROUP BY date

由于所有组都处于会话级别,因此您不需要在主表上进行任何拼合(使用数组进行交叉联接),这非常昂贵。 在最外面的WHERE中,使用子查询输入hits数组-就像在行上逐个查询。在这里您已经可以计算出REGEXP_CONTAINS(page.pagePath,r'gebak|cake')的场合了。

对于其他情况,您再次编写子查询以输入相应的数组-在第一种情况下,是customDimensions中的hits。这就像另一个子查询(子查询中的子查询)中的嵌套for-each。

在第二种情况下,我只是简单地展平-但仅在子查询中:product及其customDimensions。因此,这也是一次嵌套的for-each,因为我很懒惰并且交叉连接。我本可以编写另一个子查询而不是交叉联接,所以基本上是三嵌套的for-each(子查询中子查询中的子查询)。

由于我要计算要排除的案件,因此我的外部条件是COUNT(1)=0

我只能用ga样本数据进行测试。.所以它是未经测试的。但是我想你知道这个主意。