BigQuery - 加入和旋转大型表
Posted
技术标签:
【中文标题】BigQuery - 加入和旋转大型表【英文标题】:BigQuery - Joining and pivoting large tables 【发布时间】:2017-11-22 13:17:53 【问题描述】:我知道有一些关于旋转的帖子,我已经习惯了这些帖子来获得今天的成就(感谢 BQ 社区!)。但是这篇文章寻求一些关于在需要大量数据透视列、需要分布式表连接的情况下进行优化的建议......以及 deudping。问的不多吧!
目标:
我们有 2 个大型 BQ 表,有整整 10 年的历史需要加入:
sales_order_header(13 GB - 135 万行) sales_order_line(50GM - 500 万行)
这是典型的“标题/行”一对多关系。不幸的是,表格的数据以 2 个单独的流的形式到达,而不是 1 个文档样式,其中行嵌套在标题内,这将是理想的 - 但是对于我们的 BI 工具 (Tableau) 想要的某些视图来说,它不是那么分布的连接变得必要定期(每 60 分钟)调用以摄取“已清理”数据,即:
-
重复数据删除(两个表都是)
将标题加入行(在 salesOrderId 上)
每个都有自己的 'sourceData' namve / value paris 数组,需要解包 / 'pivot' 所以它不是数组
第 3 点本身就是一个问题。我们有一个名为 'sourceData' 的列,它基本上是核心数据所在的位置 - 它是一个字符串名称值对数组(BQ 中的一行是从数据库复制单行,因此键是列名和值单行的值)。
现在我认为问题出在这里,因为有 250 个数组条目(我们预先知道确切的数字),这相当于每个 250 个“unnest”语句,并且使用我能想到的使用子选择的最佳方法:
(SELECT val FROM UNNEST(sourceData) WHERE name = 'a') AS a, 250次
这是作为每个标题和行表代表视图的模式完成的。
因此,仅用于检索 sales_order_header 表的重复数据删除、展平/透视数组的视图的 SQL 如下所示。 sales_order_line 的视图具有相同的模式:
#standardSQL
WITH latest_snapshot_dups AS (
SELECT
salesOrderId,
PARSE_TIMESTAMP("%Y-%m-%dT%H:%M:%E*S%Ez", lastUpdated) AS lastUpdatedTimestampUTC,
sourceData,
_PARTITIONTIME AS bqPartitionTime
FROM
`project.ds.sales_order_header_refdata`
),
latest_snapshot_nodups AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY salesOrderId ORDER BY lastUpdatedTimestampUTC DESC) AS rowNum
FROM latest_snapshot_dups
)
SELECT
salesOrderId,
lastUpdatedTimestampUTC,
(SELECT val FROM UNNEST(sourceData) WHERE name = 'a') AS a,
(SELECT val FROM UNNEST(sourceData) WHERE name = 'b') AS b,
....250 of these
FROM
latest_snapshot_nodups
WHERE
rowNum = 1
虽然这里只显示一个,但我们有这两个相似的视图(总共有 250 + 300 = 550 个不嵌套/透视的唯一子查询),现在我想将标题与行视图连接起来,但遇到了一个问题立即超过子查询的限制。
假设这是要处理的数据,是否有更好的方法来做到这一点?也许是一种更好的“旋转”方式?或者更有效的方法是构建一个优化事物顺序的单一视图,而不是使用 2 个离散视图?
感谢您对 BQ 社区的帮助!
【问题讨论】:
【参考方案1】:我遇到了一个超过子查询限制的问题
您当前使用以下模式(为简单起见,删除了代码的重要部分)
#standardSQL
SELECT
salesOrderId,
(SELECT val FROM UNNEST(sourceData) WHERE name = 'a') AS a,
(SELECT val FROM UNNEST(sourceData) WHERE name = 'b') AS b,
....250 OF these
FROM latest_snapshot_nodups
试试下面的模式
#standardSQL
SELECT
salesOrderId,
MAX(IF(name = 'a', val, NULL)) AS a,
MAX(IF(name = 'b', val, NULL)) AS b,
....250 OF these
FROM latest_snapshot_nodups, UNNEST(sourceData) kv
GROUP BY salesOrderId
【讨论】:
非常感谢米哈伊尔,非常感谢!一件事 - 我可以看到 groupBy 的使用,我实际上还有大约 10 个其他列我会在投影中选择,而不仅仅是 groupBy 语句中使用的 salesOrderId(例如,一些日期和一个外部 id)。是否让 groupBy 将其限制为一个选项? 您应该只将所有分组列包含在 GROUP BY 语句中。例如,GROUP BY salesOrderId, lastUpdatedTimestampUTC
以上是关于BigQuery - 加入和旋转大型表的主要内容,如果未能解决你的问题,请参考以下文章
sql [BigQuery - Facebook产品目录]查询para obtenerelcatálogodeproductos de Kichink。 #facebook #bigqu
使用自定义目标接收器将日志导出到 BigQuery(表分区)
在 BigQuery 中恢复过期的 Firebase 表并将数据保存时间超过 60 天