ARRAY
类型描述
ARRAY<T>
类型用于表示有序元素集合,集合中的每个元素具有相同的数据类型。例如,一个整数数组可表示为[1, 2, 3]
,一个字符串数组可表示为["a", "b", "c"]
。
ARRAY<T>
表示由T类型组成的数组,T类型是Nullable的,T支持的类型有:BOOLEAN,TINYINT,SMALLINT,INT,BIGINT,LARGEINT,FLOAT,DOUBLE,DECIMAL,DATE,DATETIME,CHAR,VARCHAR,STRING,IPTV4,IPV6,STRUCT,MAP,VARIANT,JSONB,ARRAY<T>
。- 注意:上述T类型中的
JSONB
和VARIANT
只是在Doris层中的计算层支持,不支持Doris建表中使用ARRAY<JSONB>
和ARRAY<VARIANT>
。
- 注意:上述T类型中的
类型约束
ARRAY<T>
类型支持的最大嵌套深度为9。ARRAY<T>
类型之间的转换取决于T之间是否能转换,Array<T>
类型不能转成其他类型。- 例如:
ARRAY<INT>
可以转换为ARRAY<BIGINT>
,因为INT
和BIGINT
之间可以转换。 Variant
类型可以转换成Array<T>
类型。- 字符串类型可以转换成
ARRAY<T>
类型(通过解析的形式,解析失败返回 NULL)。
- 例如:
ARRAY<T>
类型在AGGREGATE
表模型中只支持REPLACE
和REPLACE_IF_NOT_NULL
,在任何表模型中都无法作为KEY列,无法作为分区分桶列。ARRAY<T>
类型的列支持ORDER BY
和GROUP BY
操作。- 支持
ORDER BY
和GROUP BY
的T类型包括:BOOLEAN,TINYINT,SMALLINT,INT,BIGINT,LARGEINT,FLOAT,DOUBLE,DECIMAL,DATE,DATETIME,CHAR,VARCHAR,STRING,IPTV4,IPV6
。
- 支持
ARRAY<T>
类型的列不支持作为JOIN KEY
,不支持在DELETE
语句中使用。
常量构造
-
使用
ARRAY()
函数可以构造一个ARRAY<T>
类型的值,T类型为参数的公共类型。-- [1, 2, 3] T 是 INT
SELECT ARRAY(1, 2, 3);
-- ["1", "2", "abc"] , T 是 STRING
SELECT ARRAY(1, 2, 'abc'); -
使用
[]
可以构造一个ARRAY<T>
类型的值,T类型为参数的公共类型。-- ["abc", "def", "efg"] T 是 STRING
SELECT ["abc", "def", "efg"];
-- ["1", "2", "abc"] , T 是 STRING
SELECT [1, 2, 'abc'];
修改类型
-
当
ARRAY
内部的元素类型为VARCHAR
时,才允许进行修改。- 只允许将
VARCHAR
的参数从小改到大。反之不行。
CREATE TABLE `array_table` (
`k` INT NOT NULL,
`array_column` ARRAY<VARCHAR(10)>
) ENGINE=OLAP
DUPLICATE KEY(`k`)
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
ALTER TABLE array_table MODIFY COLUMN array_column ARRAY<VARCHAR(20)>; - 只允许将
-
ARRAY<T>
类型的列默认值只能指定为NULL,如果指定后不能修改。
元素访问
-
使用
[k]
的方式访问ARRAY<T>
的第k个元素,k从1开始,越界之后返回NULL。SELECT [1, 2, 3][1];
+--------------+
| [1, 2, 3][1] |
+--------------+
| 1 |
+--------------+
SELECT ARRAY(1, 2, 3)[2];
+-------------------+
| ARRAY(1, 2, 3)[2] |
+-------------------+
| 2 |
+-------------------+
SELECT [[1,2,3],[2,3,4]][1][3];
+-------------------------+
| [[1,2,3],[2,3,4]][1][3] |
+-------------------------+
| 3 |
+-------------------------+ -
使用
ELEMENT_AT(ARRAY, k)
的方式访问ARRAY<T>
的第k个元素,k从1开始,越界之后返回NULL。SELECT ELEMENT_AT(ARRAY(1, 2, 3) , 2);
+--------------------------------+
| ELEMENT_AT(ARRAY(1, 2, 3) , 3) |
+--------------------------------+
| 2 |
+--------------------------------+
SELECT ELEMENT_AT([1, 2, 3] , 3);
+---------------------------+
| ELEMENT_AT([1, 2, 3] , 3) |
+---------------------------+
| 3 |
+---------------------------+
SELECT ELEMENT_AT([["abc", "def"], ["def", "gef"], [3]] , 3);
+-------------------------------------------------------+
| ELEMENT_AT([["abc", "def"], ["def", "gef"], [3]] , 3) |
+-------------------------------------------------------+
| ["3"] |
+-------------------------------------------------------+
查询加速
- Doris表中
ARRAY<T>
类型的列支持添加倒排索引,用来加速这一列执行ARRAY
函数的计算。- T类型为倒排索引支持的类型:
BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DECIMAL, DATE, DATETIME, CHAR, VARCHAR, STRING, IPTV4, IPV6
。 - 支持加速的ARRAY函数为:
ARRAY_CONTAINS, ARRAYS_OVERLAP
,但是当函数中的参数包含NULL时,会退化为普通的向量化计算。
- T类型为倒排索引支持的类型:
示例
-
多维数组
-- 创建表
CREATE TABLE IF NOT EXISTS array_table (
id INT,
two_dim_array ARRAY<ARRAY<INT>>,
three_dim_array ARRAY<ARRAY<ARRAY<STRING>>>
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
-- 插入
INSERT INTO array_table VALUES (1, [[1, 2, 3], [4, 5, 6]], [[['ab', 'cd', 'ef'], ['gh', 'ij', 'kl']], [['mn', 'op', 'qr'], ['st', 'uv', 'wx']]]);
INSERT INTO array_table VALUES (2, ARRAY(ARRAY(1, 2, 3), ARRAY(4, 5, 6)), ARRAY(ARRAY(ARRAY('ab', 'cd', 'ef'), ARRAY('gh', 'ij', 'kl')), ARRAY(ARRAY('mn', 'op', 'qr'), ARRAY('st', 'uv', 'wx'))));
-- 查询
SELECT two_dim_array[1][2], three_dim_array[1][1][2] FROM ${tableName} ORDER BY id;
+---------------------+--------------------------+
| two_dim_array[1][2] | three_dim_array[1][1][2] |
+---------------------+--------------------------+
| 2 | cd |
| 2 | cd |
+---------------------+--------------------------+ -
复杂类型嵌套
-- 创建表
CREATE TABLE IF NOT EXISTS array_map_table (
id INT,
array_map ARRAY<MAP<STRING, INT>>
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
-- 插入
INSERT INTO array_map_table VALUES (1, ARRAY(MAP('key1', 1), MAP('key2', 2)));
INSERT INTO array_map_table VALUES (2, ARRAY(MAP('key1', 1), MAP('key2', 2)))
-- 查询
SELECT array_map[1], array_map[2] FROM array_map_table ORDER BY id;
+--------------+--------------+
| array_map[1] | array_map[2] |
+--------------+--------------+
| {"key1":1} | {"key2":2} |
| {"key1":1} | {"key2":2} |
+--------------+--------------+
-- 创建表
CREATE TABLE IF NOT EXISTS array_table (
id INT,
array_struct ARRAY<STRUCT<id: INT, name: STRING>>,
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
INSERT INTO array_table VALUES (1, ARRAY(STRUCT(1, 'John'), STRUCT(2, 'Jane')));
INSERT INTO array_table VALUES (2, ARRAY(STRUCT(1, 'John'), STRUCT(2, 'Jane')));
SELECT array_struct[1], array_struct[2] FROM array_table ORDER BY id;
+-------------------------+-------------------------+
| array_struct[1] | array_struct[2] |
+-------------------------+-------------------------+
| {"id":1, "name":"John"} | {"id":2, "name":"Jane"} |
| {"id":1, "name":"John"} | {"id":2, "name":"Jane"} |
+-------------------------+-------------------------+ -
修改类型
-- 创建表
CREATE TABLE array_table (
id INT,
array_varchar ARRAY<VARCHAR(10)>
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
-- 修改 ARRAY 类型
ALTER TABLE array_table MODIFY COLUMN array_varchar ARRAY<VARCHAR(20)>;
-- 查看列类型
DESC array_table;
+---------------+--------------------+------+-------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------------+------+-------+---------+-------+
| id | int | Yes | true | NULL | |
| array_varchar | array<varchar(20)> | Yes | false | NULL | NONE |
+---------------+--------------------+------+-------+---------+-------+ -
倒排索引
-- 建表语句
CREATE TABLE `array_table` (
`k` int NOT NULL,
`array_column` ARRAY<INT>,
INDEX idx_array_column (array_column) USING INVERTED
) ENGINE=OLAP
DUPLICATE KEY(`k`)
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"replication_num" = "1"
);
-- 插入
INSERT INTO array_table VALUES (1, [1, 2, 3]), (2, [4, 5, 6]), (3, [7, 8, 9]);
-- 倒排索引会加速 ARRAY_CONTAINS 函数的执行
SELECT * FROM array_table WHERE ARRAY_CONTAINS(array_column, 5);
+------+--------------+
| k | array_column |
+------+--------------+
| 2 | [4, 5, 6] |
+------+--------------+
-- 倒排索引会加速 ARRAYS_OVERLAP 函数的执行
SELECT * FROM array_table WHERE ARRAYS_OVERLAP(array_column, [6, 9]);
+------+--------------+
| k | array_column |
+------+--------------+
| 2 | [4, 5, 6] |
| 3 | [7, 8, 9] |
+------+--------------+