arrayJoin 函数
这是一个非常不寻常的函数。
普通函数不会更改行集,而只是更改每行中的值(映射)。聚合函数压缩行集(折叠或归约)。arrayJoin
函数获取每一行并生成一个行集(展开)。
此函数以数组作为参数,并根据数组中的元素数量将源行传播到多行。所有列中的值都简单地复制,除了应用此函数的列中的值;它将被替换为相应的数组值。
示例
SELECT arrayJoin([1, 2, 3] AS src) AS dst, 'Hello', src
┌─dst─┬─\'Hello\'─┬─src─────┐
│ 1 │ Hello │ [1,2,3] │
│ 2 │ Hello │ [1,2,3] │
│ 3 │ Hello │ [1,2,3] │
└─────┴───────────┴─────────┘
arrayJoin
函数影响查询的所有部分,包括 WHERE
部分。请注意结果为 2,即使子查询返回 1 行。
示例
SELECT sum(1) AS impressions
FROM
(
SELECT ['Istanbul', 'Berlin', 'Bobruisk'] AS cities
)
WHERE arrayJoin(cities) IN ['Istanbul', 'Berlin'];
┌─impressions─┐
│ 2 │
└─────────────┘
查询可以使用多个 arrayJoin
函数。在这种情况下,转换将执行多次,并且行将被乘以。
示例
SELECT
sum(1) AS impressions,
arrayJoin(cities) AS city,
arrayJoin(browsers) AS browser
FROM
(
SELECT
['Istanbul', 'Berlin', 'Bobruisk'] AS cities,
['Firefox', 'Chrome', 'Chrome'] AS browsers
)
GROUP BY
2,
3
┌─impressions─┬─city─────┬─browser─┐
│ 2 │ Istanbul │ Chrome │
│ 1 │ Istanbul │ Firefox │
│ 2 │ Berlin │ Chrome │
│ 1 │ Berlin │ Firefox │
│ 2 │ Bobruisk │ Chrome │
│ 1 │ Bobruisk │ Firefox │
└─────────────┴──────────┴─────────┘
重要提示!
由于优化,使用多个具有相同表达式的 arrayJoin
可能不会产生预期结果。对于这些情况,请考虑使用不会影响连接结果的额外操作修改重复的数组表达式 - 例如 arrayJoin(arraySort(arr))
、arrayJoin(arrayConcat(arr, []))
示例
SELECT
arrayJoin(dice) as first_throw,
/* arrayJoin(dice) as second_throw */ -- is technically correct, but will annihilate result set
arrayJoin(arrayConcat(dice, [])) as second_throw -- intentionally changed expression to force re-evaluation
FROM (
SELECT [1, 2, 3, 4, 5, 6] as dice
);
请注意 ARRAY JOIN 在 SELECT 查询中的语法,它提供了更广泛的可能性。ARRAY JOIN
允许您一次转换多个具有相同元素数量的数组。
示例
SELECT
sum(1) AS impressions,
city,
browser
FROM
(
SELECT
['Istanbul', 'Berlin', 'Bobruisk'] AS cities,
['Firefox', 'Chrome', 'Chrome'] AS browsers
)
ARRAY JOIN
cities AS city,
browsers AS browser
GROUP BY
2,
3
┌─impressions─┬─city─────┬─browser─┐
│ 1 │ Istanbul │ Firefox │
│ 1 │ Berlin │ Chrome │
│ 1 │ Bobruisk │ Chrome │
└─────────────┴──────────┴─────────┘
或者您可以使用 元组
示例
SELECT
sum(1) AS impressions,
(arrayJoin(arrayZip(cities, browsers)) AS t).1 AS city,
t.2 AS browser
FROM
(
SELECT
['Istanbul', 'Berlin', 'Bobruisk'] AS cities,
['Firefox', 'Chrome', 'Chrome'] AS browsers
)
GROUP BY
2,
3
┌─impressions─┬─city─────┬─browser─┐
│ 1 │ Istanbul │ Firefox │
│ 1 │ Berlin │ Chrome │
│ 1 │ Bobruisk │ Chrome │
└─────────────┴──────────┴─────────┘