ClickHouse/docs/zh/query_language/functions/array_functions.md
2019-06-07 13:40:49 +03:00

21 KiB
Raw Blame History

数组函数

empty

对于空数组返回1对于非空数组返回0。 结果类型是UInt8。 该函数也适用于字符串。

notEmpty

对于空数组返回0对于非空数组返回1。 结果类型是UInt8。 该函数也适用于字符串。

length

返回数组中的元素个数。 结果类型是UInt64。 该函数也适用于字符串。

emptyArrayUInt8, emptyArrayUInt16, emptyArrayUInt32, emptyArrayUInt64

emptyArrayInt8, emptyArrayInt16, emptyArrayInt32, emptyArrayInt64

emptyArrayFloat32, emptyArrayFloat64

emptyArrayDate, emptyArrayDateTime

emptyArrayString

不接受任何参数并返回适当类型的空数组。

emptyArrayToSingle

接受一个空数组并返回一个仅包含一个默认值元素的数组。

range(N)

返回从0到N-1的数字数组。 以防万一如果在数据块中创建总长度超过100,000,000个元素的数组则抛出异常。

array(x1, ...), operator [x1, ...]

使用函数的参数作为数组元素创建一个数组。 参数必须是常量,并且具有最小公共类型的类型。必须至少传递一个参数,否则将不清楚要创建哪种类型的数组。也就是说,你不能使用这个函数来创建一个空数组(为此,使用上面描述的'emptyArray \ *'函数)。 返回'ArrayT'类型的结果,其中'T'是传递的参数中最小的公共类型。

arrayConcat

合并参数中传递的所有数组。

arrayConcat(arrays)

参数

  • arrays 任意数量的Array类型的参数. 示例
SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res
┌─res───────────┐
│ [1,2,3,4,5,6] │
└───────────────┘

arrayElement(arr, n), operator arr[n]

从数组arr中获取索引为“n”的元素。 n必须是任何整数类型。 数组中的索引从一开始。 支持负索引。在这种情况下,它选择从末尾开始编号的相应元素。例如,arr [-1]是数组中的最后一项。

如果索引超出数组的边界则返回默认值数字为0字符串为空字符串等

has(arr, elem)

检查'arr'数组是否具有'elem'元素。 如果元素不在数组中则返回0;如果在则返回1。

NULL 值的处理。

SELECT has([1, 2, NULL], NULL)

┌─has([1, 2, NULL], NULL)─┐
│                       1 │
└─────────────────────────┘

hasAll

检查一个数组是否是另一个数组的子集。

hasAll(set, subset)

参数

  • set 具有一组元素的任何类型的数组。
  • subset 任何类型的数组,其元素应该被测试为set的子集。

返回值

  • 1 如果set包含subset中的所有元素。
  • 0 否则。

特殊的定义

  • 空数组是任何数组的子集。
  • “Null”作为数组中的元素值进行处理。
  • 忽略两个数组中的元素值的顺序。

示例

SELECT hasAll([], []) returns 1.

SELECT hasAll([1, Null], [Null]) returns 1.

SELECT hasAll([1.0, 2, 3, 4], [1, 3]) returns 1.

SELECT hasAll(['a', 'b'], ['a']) returns 1.

SELECT hasAll([1], ['a']) returns 0.

SELECT hasAll([[1, 2], [3, 4]], [[1, 2], [3, 5]]) returns 0.

hasAny

检查两个数组是否存在交集。

hasAny(array1, array2)

参数

  • array1 具有一组元素的任何类型的数组。
  • array2 具有一组元素的任何类型的数组。

返回值

  • 1 如果array1array2存在交集。
  • 0 否则。

特殊的定义

  • “Null”作为数组中的元素值进行处理。
  • 忽略两个数组中的元素值的顺序。

示例

SELECT hasAny([1], []) returns 0.

SELECT hasAny([Null], [Null, 1]) returns 1.

SELECT hasAny([-128, 1., 512], [1]) returns 1.

SELECT hasAny([[1, 2], [3, 4]], ['a', 'c']) returns 0.

SELECT hasAll([[1, 2], [3, 4]], [[1, 2], [1, 2]]) returns 1.

indexOf(arr, x)

返回数组中第一个x元素的索引从1开始如果x元素不存在在数组中则返回0。

示例:

:) SELECT indexOf([1,3,NULL,NULL],NULL)

SELECT indexOf([1, 3, NULL, NULL], NULL)

┌─indexOf([1, 3, NULL, NULL], NULL)─┐
│                                 3 │
└───────────────────────────────────┘

设置为“NULL”的元素将作为普通的元素值处理。

countEqual(arr, x)

返回数组中等于x的元素的个数。相当于arrayCountelem - > elem = xarr

NULL值将作为单独的元素值处理。

示例:

SELECT countEqual([1, 2, NULL, NULL], NULL)

┌─countEqual([1, 2, NULL, NULL], NULL)─┐
│                                    2 │
└──────────────────────────────────────┘

arrayEnumerate(arr)

返回 Array [1, 2, 3, ..., length (arr) ]

此功能通常与ARRAY JOIN一起使用。它允许在应用ARRAY JOIN后为每个数组计算一次。例如

SELECT
    count() AS Reaches,
    countIf(num = 1) AS Hits
FROM test.hits
ARRAY JOIN
    GoalsReached,
    arrayEnumerate(GoalsReached) AS num
WHERE CounterID = 160656
LIMIT 10
┌─Reaches─┬──Hits─┐
│   95606 │ 31406 │
└─────────┴───────┘

在此示例中Reaches是转换次数应用ARRAY JOIN后接收的字符串Hits是浏览量ARRAY JOIN之前的字符串。在这种特殊情况下您可以更轻松地获得相同的结果

SELECT
    sum(length(GoalsReached)) AS Reaches,
    count() AS Hits
FROM test.hits
WHERE (CounterID = 160656) AND notEmpty(GoalsReached)
┌─Reaches─┬──Hits─┐
│   95606 │ 31406 │
└─────────┴───────┘

此功能也可用于高阶函数。例如,您可以使用它来获取与条件匹配的元素的数组索引。

arrayEnumerateUniq(arr, ...)

返回与源数组大小相同的数组,其中每个元素表示与其下标对应的源数组元素在源数组中出现的次数。 例如arrayEnumerateUniq\ [10,20,10,30 ]= \ [1,1,2,1 ]。

使用ARRAY JOIN和数组元素的聚合时此函数很有用。

示例:

SELECT
    Goals.ID AS GoalID,
    sum(Sign) AS Reaches,
    sumIf(Sign, num = 1) AS Visits
FROM test.visits
ARRAY JOIN
    Goals,
    arrayEnumerateUniq(Goals.ID) AS num
WHERE CounterID = 160656
GROUP BY GoalID
ORDER BY Reaches DESC
LIMIT 10
┌──GoalID─┬─Reaches─┬─Visits─┐
│   53225 │    3214 │   1097 │
│ 2825062 │    3188 │   1097 │
│   56600 │    2803 │    488 │
│ 1989037 │    2401 │    365 │
│ 2830064 │    2396 │    910 │
│ 1113562 │    2372 │    373 │
│ 3270895 │    2262 │    812 │
│ 1084657 │    2262 │    345 │
│   56599 │    2260 │    799 │
│ 3271094 │    2256 │    812 │
└─────────┴─────────┴────────┘

在此示例中每个GoalID都计算转换次数目标嵌套数据结构中的每个元素都是达到的目标我们称之为转换和会话数。如果没有ARRAY JOIN我们会将会话数计为总和Sign。但在这种特殊情况下行乘以嵌套的Goals结构因此为了在此之后计算每个会话一次我们将一个条件应用于arrayEnumerateUniqGoals.ID函数的值。

arrayEnumerateUniq函数可以使用与参数大小相同的多个数组。在这种情况下对于所有阵列中相同位置的元素元组考虑唯一性。

SELECT arrayEnumerateUniq([1, 1, 1, 2, 2, 2], [1, 1, 2, 1, 1, 2]) AS res
┌─res───────────┐
│ [1,2,1,1,2,1] │
└───────────────┘

当使用带有嵌套数据结构的ARRAY JOIN并在此结构中跨多个元素进一步聚合时这是必需的。

arrayPopBack

从数组中删除最后一项。

arrayPopBack(array)

参数

  • array 数组。

示例

SELECT arrayPopBack([1, 2, 3]) AS res
┌─res───┐
│ [1,2] │
└───────┘

arrayPopFront

从数组中删除第一项。

arrayPopFront(array)

参数

  • array 数组。

示例

SELECT arrayPopFront([1, 2, 3]) AS res
┌─res───┐
│ [2,3] │
└───────┘

arrayPushBack

添加一个元素到数组的末尾。

arrayPushBack(array, single_value)

参数

  • array 数组。
  • single_value 单个值。只能将数字添加到带数字的数组中并且只能将字符串添加到字符串数组中。添加数字时ClickHouse会自动为数组的数据类型设置single_value类型。有关ClickHouse中数据类型的更多信息请参阅“数据类型”。可以是'NULL。该函数向数组添加一个“NULL”元素数组元素的类型转换为Nullable`。

示例

SELECT arrayPushBack(['a'], 'b') AS res
┌─res───────┐
│ ['a','b'] │
└───────────┘

arrayPushFront

将一个元素添加到数组的开头。

arrayPushFront(array, single_value)

参数

  • array 数组。
  • single_value 单个值。只能将数字添加到带数字的数组中并且只能将字符串添加到字符串数组中。添加数字时ClickHouse会自动为数组的数据类型设置single_value类型。有关ClickHouse中数据类型的更多信息请参阅“数据类型”。可以是'NULL。该函数向数组添加一个“NULL”元素数组元素的类型转换为Nullable`。

示例

SELECT arrayPushBack(['b'], 'a') AS res
┌─res───────┐
│ ['a','b'] │
└───────────┘

arrayResize

更改数组的长度。

arrayResize(array, size[, extender])

参数:

  • array — 数组.
  • size — 数组所需的长度。
    • 如果size小于数组的原始大小,则数组将从右侧截断。
  • 如果size大于数组的初始大小,则使用extender值或数组项的数据类型的默认值将数组扩展到右侧。
  • extender — 扩展数组的值。可以是'NULL`。

返回值:

一个size长度的数组。

调用示例

SELECT arrayResize([1], 3)

┌─arrayResize([1], 3)─┐
│ [1,0,0]             │
└─────────────────────┘
SELECT arrayResize([1], 3, NULL)

┌─arrayResize([1], 3, NULL)─┐
│ [1,NULL,NULL]             │
└───────────────────────────┘

arraySlice

返回一个子数组,包含从指定位置的指定长度的元素。

arraySlice(array, offset[, length])

参数

  • array 数组。
  • offset 数组的偏移。正值表示左侧的偏移量负值表示右侧的缩进值。数组下标从1开始。
  • length - 子数组的长度。如果指定负值,则该函数返回[offsetarray_length - length。如果省略该值,则该函数返回[offsetthe_end_of_array]

示例

SELECT arraySlice([1, 2, NULL, 4, 5], 2, 3) AS res
┌─res────────┐
│ [2,NULL,4] │
└────────────┘

设置为“NULL”的数组元素作为普通的数组元素值处理。

arraySort([func,] arr, ...)

以升序对arr数组的元素进行排序。如果指定了func函数,则排序顺序由func函数的调用结果决定。如果func接受多个参数,那么arraySort函数也将解析与func函数参数相同数量的数组参数。更详细的示例在arraySort的末尾。

整数排序示例:

SELECT arraySort([1, 3, 3, 0]);
┌─arraySort([1, 3, 3, 0])─┐
│ [0,1,3,3]               │
└─────────────────────────┘

字符串排序示例:

SELECT arraySort(['hello', 'world', '!']);
┌─arraySort(['hello', 'world', '!'])─┐
│ ['!','hello','world']              │
└────────────────────────────────────┘

NULLNaNInf的排序顺序:

SELECT arraySort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf]);
┌─arraySort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf])─┐
│ [-inf,-4,1,2,3,inf,nan,nan,NULL,NULL]                     │
└───────────────────────────────────────────────────────────┘
  • -Inf 是数组中的第一个。
  • NULL 是数组中的最后一个。
  • NaNNULL的前面。
  • InfNaN的前面。

注意:arraySort高阶函数。您可以将lambda函数作为第一个参数传递给它。在这种情况下排序顺序由lambda函数的调用结果决定。

让我们来看一下如下示例:

SELECT arraySort((x) -> -x, [1, 2, 3]) as res;
┌─res─────┐
│ [3,2,1] │
└─────────┘

对于源数组的每个元素lambda函数返回排序键即[1 -> -1, 2 -> -2, 3 -> -3]。由于arraySort函数按升序对键进行排序,因此结果为[3,2,1]。因此,(x) -> -x lambda函数将排序设置为降序

lambda函数可以接受多个参数。在这种情况下您需要为arraySort传递与lambda参数个数相同的数组。函数使用第一个输入的数组中的元素组成返回结果使用接下来传入的数组作为排序键。例如

SELECT arraySort((x, y) -> y, ['hello', 'world'], [2, 1]) as res;
┌─res────────────────┐
│ ['world', 'hello'] │
└────────────────────┘

这里,在第二个数组([2, 1])中定义了第一个数组(['hello''world'])的相应元素的排序键,即['hello' -> 2'world' -> 1]。 由于lambda函数中没有使用x因此源数组中的实际值不会影响结果的顺序。所以world将是结果中的第一个元素hello将是结果中的第二个元素。

其他示例如下所示。

SELECT arraySort((x, y) -> y, [0, 1, 2], ['c', 'b', 'a']) as res;
┌─res─────┐
 [2,1,0] 
└─────────┘
SELECT arraySort((x, y) -> -y, [0, 1, 2], [1, 2, 3]) as res;
┌─res─────┐
 [2,1,0] 
└─────────┘

!!! 注意 为了提高排序效率, 使用了Schwartzian transform

arrayReverseSort([func,] arr, ...)

以降序对arr数组的元素进行排序。如果指定了func函数,则排序顺序由func函数的调用结果决定。如果func接受多个参数,那么arrayReverseSort函数也将解析与func函数参数相同数量的数组作为参数。更详细的示例在arrayReverseSort的末尾。

整数排序示例:

SELECT arrayReverseSort([1, 3, 3, 0]);
┌─arrayReverseSort([1, 3, 3, 0])─┐
│ [3,3,1,0]                      │
└────────────────────────────────┘

字符串排序示例:

SELECT arrayReverseSort(['hello', 'world', '!']);
┌─arrayReverseSort(['hello', 'world', '!'])─┐
│ ['world','hello','!']                     │
└───────────────────────────────────────────┘

NULLNaNInf的排序顺序:

SELECT arrayReverseSort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf]) as res;
┌─res───────────────────────────────────┐
 [inf,3,2,1,-4,-inf,nan,nan,NULL,NULL] 
└───────────────────────────────────────┘
  • Inf 是数组中的第一个。
  • NULL 是数组中的最后一个。
  • NaNNULL的前面。
  • -InfNaN的前面。

注意:arraySort高阶函数。您可以将lambda函数作为第一个参数传递给它。如下示例所示。

SELECT arrayReverseSort((x) -> -x, [1, 2, 3]) as res;
┌─res─────┐
│ [1,2,3] │
└─────────┘

数组按以下方式排序: The array is sorted in the following way:

  1. 首先根据lambda函数的调用结果对源数组[1, 2, 3])进行排序。 结果是[3, 2, 1]。
  2. 反转上一步获得的数组。 所以,最终的结果是[1, 2, 3]。

lambda函数可以接受多个参数。在这种情况下您需要为arrayReverseSort传递与lambda参数个数相同的数组。函数使用第一个输入的数组中的元素组成返回结果使用接下来传入的数组作为排序键。例如

SELECT arrayReverseSort((x, y) -> y, ['hello', 'world'], [2, 1]) as res;
┌─res───────────────┐
 ['hello','world'] 
└───────────────────┘

在这个例子中,数组按以下方式排序:

  1. 首先根据lambda函数的调用结果对源数组['hello''world'])进行排序。 其中,在第二个数组([2,1])中定义了源数组中相应元素的排序键。 所以,排序结果['world''hello']。
  2. 反转上一步骤中获得的排序数组。 所以,最终的结果是['hello''world']。

其他示例如下所示。

SELECT arrayReverseSort((x, y) -> y, [4, 3, 5], ['a', 'b', 'c']) AS res;
┌─res─────┐
 [5,3,4] 
└─────────┘
SELECT arrayReverseSort((x, y) -> -y, [4, 3, 5], [1, 2, 3]) AS res;
┌─res─────┐
 [4,3,5] 
└─────────┘

arrayUniq(arr, ...)

如果传递一个参数,则计算数组中不同元素的数量。 如果传递了多个参数,则它计算多个数组中相应位置的不同元素元组的数量。

如果要获取数组中唯一项的列表可以使用arrayReduce'groupUniqArray'arr

arrayJoin(arr)

一个特殊的功能。请参见“ArrayJoin函数”部分。

arrayDifference(arr)

返回一个数组,其中包含所有相邻元素对之间的差值。例如:

SELECT arrayDifference([1, 2, 3, 4])
┌─arrayDifference([1, 2, 3, 4])─┐
│ [0,1,1,1]                     │
└───────────────────────────────┘

arrayDistinct(arr)

返回一个包含所有数组中不同元素的数组。例如:

SELECT arrayDistinct([1, 2, 2, 3, 1])
┌─arrayDistinct([1, 2, 2, 3, 1])─┐
│ [1,2,3]                        │
└────────────────────────────────┘

arrayEnumerateDense(arr)

返回与源数组大小相同的数组指示每个元素首次出现在源数组中的位置。例如arrayEnumerateDense[10,20,10,30]= [1,2,1,3]。

arrayIntersect(arr)

返回所有数组元素的交集。例如:

SELECT
    arrayIntersect([1, 2], [1, 3], [2, 3]) AS no_intersect,
    arrayIntersect([1, 2], [1, 3], [1, 4]) AS intersect
┌─no_intersect─┬─intersect─┐
│ []           │ [1]       │
└──────────────┴───────────┘

arrayReduce(agg_func, arr1, ...)

将聚合函数应用于数组并返回其结果。如果聚合函数具有多个参数,则此函数可应用于相同大小的多个数组。

arrayReduce'agg_func'arr1... - 将聚合函数agg_func应用于数组arr1 ...。如果传递了多个数组则相应位置上的元素将作为多个参数传递给聚合函数。例如SELECT arrayReduce'max'[1,2,3]= 3

arrayReverse(arr)

返回与源数组大小相同的数组,包含反转源数组的所有元素的结果。

来源文章