BigQuery SQL:将视图 A 中的子查询作为嵌套表嵌入视图 B

Posted

技术标签:

【中文标题】BigQuery SQL:将视图 A 中的子查询作为嵌套表嵌入视图 B【英文标题】:BigQuery SQL: Embedding subqueries from View A as nested tables in View B 【发布时间】:2019-07-09 23:33:55 【问题描述】:

我正在尝试使用标准 SQL 将来自两个平面相关 BigQuery 视图的数据组合到单个嵌套表架构中

我有两个相似的表:

分析数据:全球时间跨度内每分钟一行

-------------------------------------------------------------------
minute_index | users | users_new | ...
-------------------------------------------------------------------
     1312017 |     8 |         3 | ...
     1312018 |     9 |         2 | ...
     1312019 |     5 |         1 | ...
     1312020 |     3 |         0 | ...
     1312021 |     5 |         2 | ...
     1312023 |     4 |         3 | ...
     1312024 |     7 |         4 | ...
     1312025 |     6 |         3 | ...
     1312026 |     9 |         4 | ...

事件数据:每个发生的外部事件占一行

----------------------------------------
minute_index | event                   |
----------------------------------------
     1312019 | "TV Spot Broadcast"     |
     1312023 | "Radio Spot Broadcast"  |
     1312026 | "Radio Spot Broadcast"  |

我正在尝试将它们合并到一个表中,其中新表中的每一行都包含 Analytics 表的一个子集,该子集跨越该表和接下来的几分钟(我们称之为 5):

-----------------------------------------------------------------------------
minute_index | event                    | window_treated                   |
-----------------------------------------------------------------------------
     1312019 | "TV Spot Broadcast"      | minute_index | users | users_new |
                                        |------------------------------------
                                        |      1312019 |     5 |         1 |
                                        |      1312020 |     3 |         0 |
                                        |      1312021 |     5 |         2 |
                                        |      1312023 |     4 |         3 |
                                        |      1312024 |     7 |         4 |
-----------------------------------------------------------------------------
     1312023 | "Radio Spot Broadcast"   | minute_index | users | users_new |
                                        |------------------------------------
                                        |      1312023 |     4 |         3 |
                                        |      1312020 |     3 |         0 |
                                        |      1312021 |     5 |         2 |
                                        |      1312023 |     4 |         3 |
                                        |      1312024 |     7 |         4 |

我实际上已经能够构建这样的嵌套表,但只能通过构建和连接复杂的中间表集合来显然比它们应该的要复杂得多,如果我只能想了解如何在单个查询中执行此类操作。

这只是我尝试过的各种方法的一个示例......

SELECT
  ed.timestamp AS timestamp,
  ed.minute_index AS minute_index,
  (SELECT AS STRUCT 
     ad.minute_index, ad.users, ad.users_new
   FROM `my_project.my_dataset.analytics_data` ad 
   WHERE (ad.minute_index >= ed.minute_index) 
      AND (ad.minute_index < (ed.minute_index + 5))
   ORDER BY
      ed.minute_index) AS units_treated
FROM
  `my_project.my_dataset.event_data` ed

但它也是似乎接近的几个之一,但都导致相同的验证器错误:

Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN.

【问题讨论】:

我已经能够在这里找到少量接近但不完全的答案,比如这个——Avoid correlated subqueries error in BigQuery——但他们通常没有提供足够的指导去哪里我得走了。 【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
SELECT 
  ed.minute_index, 
  event, 
  ARRAY_AGG(ad) window_treated
FROM `my_project.my_dataset.event_data` ed
JOIN `my_project.my_dataset.analytics_data` ad
ON ad.minute_index BETWEEN ed.minute_index AND ed.minute_index + 5
GROUP BY ed.minute_index, event   

如果应用于您问题的样本数据 - 结果将如下所示

如您所见 - 我确实遵循了错误消息 Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN. 中的建议,并将 correlated subquery 转换为 JOIN

【讨论】:

非常感谢,@mikhail -- 我实际上希望你能插话。;) 明确地说,我确实确​​实明白这基本上是我所需要的要做,但我已经尝试了您描述的方法的几种变体,并且反复缠绕在轴上,试图找出使用ARRAY_AGGARRAY' with GROUP BY, SELECT AS STRUCT`的确切语法等。 当然。有道理。现在希望这种模式将来会对您有所帮助:o) 实际上,我认为我的核心问题之一只是出于习惯使用LEFT JOIN,而不是赤裸裸的/内在的JOIN。我尝试了与您的建议非常相似的非常,但不断得到LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.如果我对我的模式的其余有足够的信心,我可能会立即意识到“我应该只使用内部连接”,但那时我已经折腾得够多了,这只是又一个错误,这意味着我需要了解 h-ll 发生了什么。 @LaurentStanevich - 我看到你不接受答案 - 有什么特别的原因吗?只是好奇 不,完全没有。我认为这可能只是一个错误的点击。 (实际上,现在我正在考虑它,我认为这可能是我的新型触摸屏笔记本电脑的问题。我正在向我的儿子解释你的解决方案——今年夏天和我一起实习的一名 CS 专业的学生——而我我猜我可能在我兴奋地对着屏幕做手势时无意中点击了复选标记。)

以上是关于BigQuery SQL:将视图 A 中的子查询作为嵌套表嵌入视图 B的主要内容,如果未能解决你的问题,请参考以下文章

支持标准 SQL 中的视图

使用 EXECUTE IMMEDIATE 保存带有动态 SQL 的 BigQuery 视图

如何在 Datalab 的 api 中使用 Bigquery 中的子查询?

使用 Apps 脚本定义/创建 BigQuery 保存视图的 SQL 查询

如何在文件中从SQL源创建BigQuery视图(Windows命令行)

如何通过 Datalab 查询 BigQuery 视图?