ARRAY JOIN 子句
对于包含数组列的表,生成一个新表,其包含初始列每个单独数组元素的列,同时其他列的值会被重复,这是一个常见的操作。这就是 ARRAY JOIN
子句的基本功能。
其名称来源于它可以被视为与数组或嵌套数据结构执行 JOIN
。其意图与 arrayJoin 函数相似,但子句的功能更为广泛。
语法:
支持的 ARRAY JOIN
类型如下所示:
ARRAY JOIN
- 在基本情况下,空数组不会包含在JOIN
的结果中。LEFT ARRAY JOIN
-JOIN
的结果包含具有空数组的行。空数组的值被设置为数组元素类型的默认值(通常是 0、空字符串或 NULL)。
基本的 ARRAY JOIN 示例
以下示例演示了 ARRAY JOIN
和 LEFT ARRAY JOIN
子句的用法。我们创建一个包含 Array 类型列的表并插入值:
以下示例使用 ARRAY JOIN
子句:
下一个示例使用 LEFT ARRAY JOIN
子句:
使用别名
可以在 ARRAY JOIN
子句中为数组指定别名。在这种情况下,可以通过该别名访问数组项,但数组本身则通过原始名称访问。例如:
使用别名,您可以对外部数组执行 ARRAY JOIN
。例如:
可以在 ARRAY JOIN
子句中使用多个用逗号分隔的数组。在这种情况下,JOIN
是同时进行的(直接求和,而不是笛卡尔积)。请注意,所有数组默认必须具有相同的大小。例如:
以下示例使用 arrayEnumerate 函数:
可以通过使用 SETTINGS enable_unaligned_array_join = 1
来连接具有不同大小的多个数组。示例:
ARRAY JOIN 与嵌套数据结构
ARRAY JOIN
也适用于 嵌套数据结构:
在 ARRAY JOIN
中指定嵌套数据结构的名称时,其含义与与其组成的所有数组元素的 ARRAY JOIN
相同。以下示例列出:
这种变体也是合理的:
可以为嵌套数据结构使用别名,以选择 JOIN
结果或源数组。例如:
使用 arrayEnumerate 函数的示例:
实现细节
运行 ARRAY JOIN
时,查询执行顺序是经过优化的。虽然 ARRAY JOIN
必须始终在查询中的 WHERE/PREWHERE 子句之前指定,但从技术上讲,它们可以以任何顺序执行,除非 ARRAY JOIN
的结果用于过滤。处理顺序由查询优化器控制。
与短路函数评估的不兼容性
短路函数评估 是一种优化特定函数(如 if
、multiIf
、and
和 or
)中复杂表达式执行的功能。它可以防止在这些函数执行过程中可能发生的异常,例如除以零。
arrayJoin
始终被执行,并且不支持短路函数评估。这是因为它是一个在查询分析和执行过程中单独处理的独特函数,并需要额外的逻辑,这与短路函数执行不兼容。原因是结果中的行数依赖于 arrayJoin
的结果,而实现 arrayJoin
的延迟执行过于复杂且成本高昂。