我知道有一些关于旋转的帖子,我已经习惯了今天的位置(感谢BQ社区!)。但是这篇文章寻求一些关于优化这一点的建议,其中需要大量的枢轴列,需要分布式表连接....以及否定。没问题太多了!
目标:
我们有2个大型BQ表,有10年的历史需要加入:
sales_order_header(13 GB - 135万行) sales_order_line(50GM - 500万行)
这是一个典型的标题/行'一对多的关系。不幸的是,这些表的数据作为2个单独的流而不是1个文档样式到达,其中行嵌套在标题内,这将是理想的 - 但是对于我们的BI工具(Tableau)想要的一些视图,它不是那么分散的连接是必要的定期(每60分钟)呼叫摄取'清洁'数据是:
第3点本身就是一个问题。我们有一个名为' sourceData'这基本上是核心数据的位置 - 它是一个字符串名称值对的数组(BQ中的一行是来自DB的单行的复制,因此键是列名,值是单行的值)。
现在我认为这里存在问题,因为有250个阵列条目(我们知道前面的确切数字),这相当于250'不需要'每个语句并使用我能想到的最佳方法使用子选择:
(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社区的帮助!
答案 0 :(得分:1)
我直接遇到超出子查询限制的问题
您目前使用的是以下模式(为简单起见,删除了重要的代码部分)
Lex code hook lambda function
尝试以下模式
#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