更新时间:2025-09-18 GMT+08:00

复杂类型

DataArtsFabric SQL支持从orc/parquet文件中读取复杂类型列,当前仅支持读取,且仅支持struct和array类型,对于array类型,暂不支持多维数组查询。

复杂类型DDL

当前DDL仅支持STRUCT和ARRAY类型。

定义语法如下:

  • ARRAY:定义语法为ARRAY<data_type>。
  • STRUCT:定义语法为STRUCT<col_name : data_type, ...>。

其中data_type表示数据类型,可以是基础类型和复杂类型,基础类型请参见与LakeFormation数据类型映射关系

DDL示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-- 创建包含复杂类型的external表
CREATE EXTERNAL TABLE test_table (
    name TEXT,
    address STRUCT<zip:INT, city:TEXT>,
    tags ARRAY<TEXT>,
    logs ARRAY<STRUCT<term:TEXT, time:TIMESTAMP>>
) store as orc location 'obs://test/test1';

-- 建表后,可查看LakeFormation完整定义
DESCRIBE test_table;

复杂类型DQL

  • Struct类型支持点查的方式直接获取内部元素,点查时表列名需用括号”()”包裹。
  • Array的使用与一般数组类似,通过下标指定返回某个元素,需要注意的是下标起始位置索引为1。

DQL示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- 查询复杂类型数据
SELECT * FROM test_table;
  name   |       address       |       tags         |                               logs                                 
---------+---------------------+--------------------+--------------------------------------------------------------------- 
 Alice   | (10001,New York)    | {friend,colleague} | {"(login,2024-01-01 00:00:00)","(login,2024-02-01 00:00:00)"}
 Bob     | (90001,Los Angeles) | {family}           | {"(purchase,2024-02-15 00:00:00)","(purchase,2024-02-10 00:00:00)"}
 Charlie | (60601,Chicago)     | {friend,hobby}     | {NULL}
(3 rows)

-- 提取struct元素
SELECT (address).city, (address).zip FROM test_table;
  city   |    zip   
---------+----------
  10001  | New York 
  90001  | Angeles  
  60601  | Chicago  
(3 rows)

-- 提取array元素
SELECT tags[1], tags[2] FROM test_table;
  tags   |   tags   
---------+----------
  friend | colleague 
  family |   
  friend | hobby  
(3 rows)

复杂类型转jsonb

当前复杂类型包括STRUCT和ARRAY通过JSON的方式读取,用户在读取数据以后需要显式转换为对应的数据类型。

DQL示例(jsonb完整操作符和函数说明请参见JSON/JSONB函数和操作符):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
--  -> 通过键或索引提取 JSON 对象或数组的元素
SELECT name, address, tags, logs->0->'term' FROM test_table;
  name   |                address                |          tags           |  ?column?  
---------+---------------------------------------+-------------------------+------------
 Alice   | {"zip": 10001, "city": "New York"}    | ["friend", "colleague"] | "login"
 Bob     | {"zip": 90001, "city": "Los Angeles"} | ["family"]              | "purchase"
 Charlie | {"zip": 60601, "city": "Chicago"}     | ["friend", "hobby"]     | 
(3 rows)

--  ->> 提取元素并转为 text
SELECT name, address FROM test_table WHERE address->>'zip' = '10001';
 name  |              address               
-------+------------------------------------
 Alice | {"zip": 10001, "city": "New York"}
(1 row)

--  @> 数组包含元素,左侧数组包含右侧数组内全部元素
SELECT name, tags FROM test_table WHERE tags @> '["friend"]'::jsonb;
  name   |          tags           
---------+-------------------------
 Alice   | ["friend", "colleague"]
 Charlie | ["friend", "hobby"]
(2 rows)

--  类型显示转换,先使用 ->> 获取为字符,再进行类型转换
SELECT (logs->0->>'time')::TIMESTAMP FROM test_table;
      timestamp      
---------------------
 2024-01-01 00:00:00
 2024-02-15 00:00:00

(3 rows)