我收到以下错误
(100032) 执行查询作业时出错。消息:无法识别的名称:嵌套
nested
我的临时表在哪里声明为 WITH 子句。尝试的代码如下:
WITH nested AS
(
SELECT e.my_id , SPLIT(secondary_ids, '<#>') AS arr_secondary_ids
FROM table_with_delimited_string_column e
WHERE my_id = 1234
)
SELECT DISTINCT a
FROM UNNEST(nested.arr_secondary_ids) a
Run Code Online (Sandbox Code Playgroud)
SPLIT 函数将返回一个 ARRAY 类型,该类型稍后将被取消嵌套。
从 Google Cloud 文档中,这是有效的:
SELECT *
FROM UNNEST(ARRAY<STRUCT<x INT64, y STRING>>[(1, 'foo'), (3, 'bar')]);
Run Code Online (Sandbox Code Playgroud)
这也有效:
WITH sequences AS
(SELECT 1 AS id, [0, 1, 1, 2, 3, 5] AS some_numbers
UNION ALL SELECT 2 AS id, [2, 4, 8, 16, 32] AS some_numbers
UNION ALL SELECT 3 AS id, [5, 10] AS some_numbers)
SELECT id, flattened_numbers
FROM sequences
CROSS JOIN UNNEST(sequences.some_numbers) AS flattened_numbers;
Run Code Online (Sandbox Code Playgroud)
因此,从技术上讲,由 UNNEST 生成的值表应该能够直接从SELECT *
. 此外,临时表中的列应该能够被取消嵌套。
但是,当我回到我的用例时,...UNNEST(nested.arr_secondary_ids)
将产生上述错误。
我希望能够立即查询它,因为我在结果表上得到了重复的值,正如你所看到的,我想用DISTINCT
. 当前的解决方法是什么?产生此错误的技术原因是什么?想知道它是否与我缺少的 ARRAY 或 STRUCT 类型有关...
以前的答案对理解为什么nested
需要做出很大贡献。但是,我找到了主键(又名my_id
)何时对定义重复项很重要以及何时不重要的最佳方案。
在我的真实场景中,很my_id
重要,我不想要重复的my_id
,对secondary_id
。没有办法避免一个CROSS JOIN
或多个表引用,因为源 CTE 表必须直接在 FROM 子句中(如@pruthvi-kumar和@mikhail-berlyant 所述)。@mikhail-berlyant还指出,这只是一种扁平化操作,因此CROSS JOIN
在这里也不是一项昂贵的操作。总而言之,解决方案是:
WITH nested AS
(
SELECT e.my_id , SPLIT(secondary_ids, '<#>') AS arr_secondary_ids
FROM table_with_delimited_string_column e
)
SELECT DISTINCT nested.entity_id, a
FROM nested CROSS JOIN UNNEST(arr_secondary_ids) a
Run Code Online (Sandbox Code Playgroud)
但是,在发布的问题中,我已经说明了固定my_id
= 1234,因此该列不会成为重复项的决定因素。在这种情况下,可以通过对要取消嵌套的数组使用标量子查询来跳过相关的交叉连接。这里的最佳解决方案是:
WITH nested AS
(
SELECT e.my_id , SPLIT(secondary_ids, '<#>') AS arr_secondary_ids
FROM table_with_delimited_string_column e
WHERE my_id = 1234
)
SELECT DISTINCT a
FROM UNNEST((SELECT arr_secondary_ids FROM nested)) AS a
Run Code Online (Sandbox Code Playgroud)
请注意将 SELECT 包裹在 unnest 中的括号。它们是必需的,否则您会收到如下消息:
UNNEST 的参数是一个表达式,而不是一个查询;要将查询用作表达式,必须用额外的括号将查询包装起来,使其成为标量子查询表达式
nested
my_id
过滤后也应该只有1行,否则你会发现一个讨厌的
标量子查询产生多个元素