跳到主要内容
跳到主要内容

ARRAY JOIN 子句

对于包含数组列的表,生成一个新表,其包含初始列每个单独数组元素的列,同时其他列的值会被重复,这是一个常见的操作。这就是 ARRAY JOIN 子句的基本功能。

其名称来源于它可以被视为与数组或嵌套数据结构执行 JOIN。其意图与 arrayJoin 函数相似,但子句的功能更为广泛。

语法:

支持的 ARRAY JOIN 类型如下所示:

  • ARRAY JOIN - 在基本情况下,空数组不会包含在 JOIN 的结果中。
  • LEFT ARRAY JOIN - JOIN 的结果包含具有空数组的行。空数组的值被设置为数组元素类型的默认值(通常是 0、空字符串或 NULL)。

基本的 ARRAY JOIN 示例

以下示例演示了 ARRAY JOINLEFT 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 的结果用于过滤。处理顺序由查询优化器控制。

与短路函数评估的不兼容性

短路函数评估 是一种优化特定函数(如 ifmultiIfandor)中复杂表达式执行的功能。它可以防止在这些函数执行过程中可能发生的异常,例如除以零。

arrayJoin 始终被执行,并且不支持短路函数评估。这是因为它是一个在查询分析和执行过程中单独处理的独特函数,并需要额外的逻辑,这与短路函数执行不兼容。原因是结果中的行数依赖于 arrayJoin 的结果,而实现 arrayJoin 的延迟执行过于复杂且成本高昂。