ARRAY
ARRAYARRAY
是有序的同类型元素序列,支持按下标访问、切片、集合运算和高阶函数。适合存储标签列表、评分序列、日志路径等场景。
与复杂类型的选型参考:
类型 结构 适合场景 ARRAY<T>ARRAY<T>
有序列表,元素类型统一 标签、评分、ID 列表 MAP<K,V>MAP<K,V>
键值对,键类型统一 动态属性、名称到值的映射 STRUCT<f:T,...>STRUCT<f:T,...>
命名字段,类型各异 固定结构的对象,如用户信息
语法与定义
类型声明
ARRAY<elementType>
构造方式
-- 方括号字面量(推荐)
[value1, value2, ...]
-- ARRAY() 构造函数
ARRAY(value1, value2, ...)
字面量类型推断 :整数字面量推断为
array<int>array<int>
,小数推断为
array<decimal(p,s)>array<decimal(p,s)>
:
SELECT typeof([1, 2, 3]), -- array<int>
typeof([1.5, 2.5]), -- array<decimal(2,1)>
typeof(['a', 'b']); -- array<string>
元素访问 :下标从
00
开始,越界或负数下标返回
NULLNULL
:
SELECT [10, 20, 30][0], -- 10
[10, 20, 30][2], -- 30
[10, 20, 30][-1], -- NULL(负数不支持)
[10, 20, 30][5]; -- NULL(越界)
建表与写入
CREATE TABLE doc_array_demo (
id INT,
tags ARRAY<STRING>,
scores ARRAY<INT>
);
INSERT INTO doc_array_demo VALUES
(1, ['read', 'write', 'admin'], [95, 87, 92]),
(2, ['read'], [78]),
(3, ['read', 'write'], [88, NULL, 91]);
查询基本信息:
SELECT id, tags, tags[0] AS first_tag, size(tags) AS tag_count
FROM doc_array_demo
ORDER BY id;
id tags first_tag tag_count 1 ["read","write","admin"] read 3 2 ["read"] read 1 3 ["read","write"] read 2
常用函数
函数 说明 示例结果 size(arr)size(arr)
/ cardinality(arr)cardinality(arr)
元素个数 size([1,2,3])size([1,2,3])
→ 33
array_contains(arr, val)array_contains(arr, val)
是否包含某值 array_contains([1,2,3], 2)array_contains([1,2,3], 2)
→ truetrue
array_position(arr, val)array_position(arr, val)
首次出现的位置(1-based ),不存在返回 00
array_position([10,20,30,20], 20)array_position([10,20,30,20], 20)
→ 22
array_append(arr, val)array_append(arr, val)
追加到末尾 array_append([1,2], 3)array_append([1,2], 3)
→ [1,2,3][1,2,3]
array_prepend(arr, val)array_prepend(arr, val)
追加到开头 array_prepend([1,2], 0)array_prepend([1,2], 0)
→ [0,1,2][0,1,2]
array_remove(arr, val)array_remove(arr, val)
移除所有匹配元素(val 为 NULL 时返回 NULL) array_remove([1,2,3,2], 2)array_remove([1,2,3,2], 2)
→ [1,3][1,3]
array_distinct(arr)array_distinct(arr)
去重,保留首次出现顺序 array_distinct([1,2,2,3])array_distinct([1,2,2,3])
→ [1,2,3][1,2,3]
array_sort(arr)array_sort(arr)
升序排序,NULL 排末尾 array_sort([3,1,NULL,2])array_sort([3,1,NULL,2])
→ [1,2,3,null][1,2,3,null]
sort_array(arr, asc)sort_array(arr, asc)
指定升降序,NULL 始终排末尾 sort_array([3,1,2], false)sort_array([3,1,2], false)
→ [3,2,1][3,2,1]
array_max(arr)array_max(arr)
最大值(忽略 NULL) array_max([3,1,5,2])array_max([3,1,5,2])
→ 55
array_min(arr)array_min(arr)
最小值(忽略 NULL) array_min([3,1,5,2])array_min([3,1,5,2])
→ 11
array_union(arr1, arr2)array_union(arr1, arr2)
合并并去重 array_union([1,2], [2,3])array_union([1,2], [2,3])
→ [1,2,3][1,2,3]
array_intersect(arr1, arr2)array_intersect(arr1, arr2)
交集 array_intersect([1,2,3], [2,3,4])array_intersect([1,2,3], [2,3,4])
→ [2,3][2,3]
array_except(arr1, arr2)array_except(arr1, arr2)
差集(arr1 中有、arr2 中没有的元素) array_except([1,2,3], [2])array_except([1,2,3], [2])
→ [1,3][1,3]
flatten(arr)flatten(arr)
展平一层嵌套数组 flatten([[1,2],[3,4]])flatten([[1,2],[3,4]])
→ [1,2,3,4][1,2,3,4]
slice(arr, start, length)slice(arr, start, length)
切片,start 从 1 开始 ,支持负数从末尾数 slice([10,20,30,40], 2, 2)slice([10,20,30,40], 2, 2)
→ [20,30][20,30]
arrays_zip(arr1, arr2, ...)arrays_zip(arr1, arr2, ...)
逐元素合并为 STRUCT 数组 见下方示例 array_join(arr, sep)array_join(arr, sep)
元素转字符串并拼接 array_join([1,2,3], ',')array_join([1,2,3], ',')
→ '1,2,3''1,2,3'
array_join(arr, sep, nullReplacement)array_join(arr, sep, nullReplacement)
NULL 元素用替换串填充 array_join(['a',NULL,'c'], ',', 'N/A')array_join(['a',NULL,'c'], ',', 'N/A')
→ 'a,N/A,c''a,N/A,c'
切片示例
SELECT slice([10, 20, 30, 40, 50], 2, 3) AS mid, -- [20,30,40]
slice([10, 20, 30, 40, 50], -2, 2) AS tail; -- [30,40]
⚠️
sliceslice
的起始位置是
1-based ,与下标访问(0-based)不一致。
arrays_zip 示例
arrays_ziparrays_zip
将多个数组逐元素合并为 STRUCT 数组,字段名自动生成为
"0""0"
、
"1""1"
、
"2""2"
:
SELECT arrays_zip([1, 2, 3], ['a', 'b', 'c']) AS zipped;
-- 返回:[{"0":1,"1":"a"},{"0":2,"1":"b"},{"0":3,"1":"c"}]
高阶函数
TRANSFORMTRANSFORM
和
FILTERFILTER
支持 lambda 表达式,对数组逐元素处理:
-- TRANSFORM:对每个元素应用函数
SELECT TRANSFORM([1, 2, 3, 4, 5], x -> x * x) AS squares;
-- 返回:[1,4,9,16,25]
-- FILTER:保留满足条件的元素
SELECT FILTER([1, 2, 3, 4, 5, 6], x -> x % 2 = 0) AS evens;
-- 返回:[2,4,6]
组合使用示例——先过滤再变换:
SELECT TRANSFORM(
FILTER([1, 2, 3, 4, 5, 6], x -> x % 2 = 0),
x -> x * 10
) AS result;
-- 返回:[20,40,60]
聚合与展开
ARRAY_AGG — 行转列
将多行值聚合为一个数组,支持
ORDER BYORDER BY
和
DISTINCTDISTINCT
(两者不能同时使用):
SELECT dept, ARRAY_AGG(name ORDER BY name) AS members
FROM (
SELECT 'Alice' AS name, 'Eng' AS dept UNION ALL
SELECT 'Bob', 'Eng' UNION ALL
SELECT 'Carol','HR' UNION ALL
SELECT 'Dave', 'HR'
) t
GROUP BY dept
ORDER BY dept;
dept members Eng ["Alice","Bob"] HR ["Carol","Dave"]
-- DISTINCT 去重(不能同时带 ORDER BY)
SELECT ARRAY_AGG(DISTINCT x) AS deduped
FROM (SELECT 1 AS x UNION ALL SELECT 2 UNION ALL SELECT 1 UNION ALL SELECT 3) t;
-- 返回:[1,2,3]
EXPLODE — 列转行
EXPLODEEXPLODE
将数组展开为多行,配合
LATERAL VIEWLATERAL VIEW
保留原始行的其他字段:
SELECT id, tag
FROM doc_array_demo
LATERAL VIEW EXPLODE(tags) tmp AS tag
ORDER BY id, tag;
id tag 1 admin 1 read 1 write 2 read 3 read 3 write
POSEXPLODEPOSEXPLODE
额外返回元素在数组中的位置(0-based):
SELECT id, pos, tag
FROM doc_array_demo
LATERAL VIEW POSEXPLODE(tags) tmp AS pos, tag
WHERE id = 1;
id pos tag 1 0 read 1 1 write 1 2 admin
类型转换
-- 转换元素类型,用尖括号指定目标类型
SELECT CAST([1, 2, 3] AS ARRAY<BIGINT>); -- [1,2,3](bigint)
SELECT CAST([1, 2, 3] AS ARRAY<STRING>); -- ["1","2","3"]
-- 嵌套数组类型转换(元素类型转为目标类型的字符串表示)
SELECT CAST(ARRAY(ARRAY(1, 2), ARRAY(3, 4)) AS ARRAY<ARRAY<BIGINT>>);
-- 返回:[["1","2"],["3","4"]]
CAST to STRING 与 TO_JSON 的格式区别 :
SELECT CAST([1, 2, 3] AS STRING); -- [1, 2, 3](逗号后有空格)
SELECT TO_JSON([1, 2, 3]); -- [1,2,3](无空格,标准 JSON)
⚠️ 字符串
'[1,2,3]''[1,2,3]'
不能直接 CAST 为 ARRAY,必须通过
SPLITSPLIT
等函数处理后再构造。
NULL 处理
-- ARRAY 可以包含 NULL 元素
SELECT [1, 2, NULL, 3];
-- 返回:[1,2,null,3]
-- array_contains 查找 NULL 返回 NULL,不是 true 或 false
SELECT array_contains([1, 2, NULL], NULL);
-- 返回:null
-- array_remove 移除 NULL 返回 NULL(不是移除 NULL 元素后的数组)
SELECT array_remove([1, NULL, 2], NULL);
-- 返回:null
-- array_distinct 保留一个 NULL
SELECT array_distinct([1, NULL, 2, NULL, 3]);
-- 返回:[1,null,2,3]
注意事项
下标从 00
开始;sliceslice
起始位置从 11
开始。两者不一致,使用前注意区分。
ARRAY 支持 ==
相等比较,不支持 >>
、<<
等大小比较,也不支持作为 GROUP BY 键或 JOIN 键。
TRANSFORMTRANSFORM
和 FILTERFILTER
是 lambda 高阶函数,AGGREGATEAGGREGATE
/REDUCEREDUCE
暂不支持。
ARRAY_AGGARRAY_AGG
的 DISTINCTDISTINCT
和 ORDER BYORDER BY
不能同时使用。
array_positionarray_position
返回 1-based 位置,不存在时返回 00
,与下标访问(0-based)不同。
相关文档