STRUCT

STRUCT
STRUCT
是复合数据类型,将多个不同类型的字段组合为一个命名字段集合。适合将关联数据存储在同一列中,如将用户的姓名、年龄、状态作为一个整体存储,或在 ARRAY 中存储结构化对象。

与复杂类型的选型参考:

类型结构适合场景
STRUCT<f:T,...>
STRUCT<f:T,...>
命名字段,类型各异固定结构的对象,字段名在建表时确定
MAP<K,V>
MAP<K,V>
键值对,键类型统一动态属性,字段数量不固定
ARRAY<T>
ARRAY<T>
有序列表,元素类型统一标签、评分、ID 列表

语法与定义

类型声明

STRUCT<field1_name: field1_type, field2_name: field2_type, ...>

构造函数

-- named_struct:指定字段名(推荐) named_struct('field1_name', value1, 'field2_name', value2, ...) -- struct:自动生成字段名 col1、col2、... struct(value1, value2, ...)

字段访问:字段名大小写不敏感:

named_struct('Name', 'Alice', 'age', 30).name -- Alice named_struct('Name', 'Alice', 'age', 30).Name -- Alice(同一字段)

建表与写入

CREATE TABLE doc_struct_demo ( id INT, person STRUCT<name: STRING, age: INT, active: BOOLEAN> ); INSERT INTO doc_struct_demo VALUES (1, named_struct('name', 'Alice', 'age', 30, 'active', true)), (2, named_struct('name', 'Bob', 'age', 25, 'active', false)), (3, named_struct('name', 'Carol', 'age', NULL, 'active', true));

查询整列与字段访问:

SELECT id, person, person.name, person.age, person.active FROM doc_struct_demo ORDER BY id;

idpersonnameageactive
1{"name":"Alice","age":30,"active":true}Alice30true
2{"name":"Bob","age":25,"active":false}Bob25false
3{"name":"Carol","age":null,"active":true}CarolNULLtrue

构造函数对比

-- named_struct:字段名自定义 SELECT named_struct('company', 'ClickZetta', 'headcount', 5) AS s1; -- 返回:{"company":"ClickZetta","headcount":5} -- struct:字段名自动生成为 col1、col2、... SELECT struct('Alice', 30, true) AS s2; -- 返回:{"col1":"Alice","col2":30,"col3":true}

修改字段值

STRUCT 字段不能单独修改,需使用

struct_update()
struct_update()
函数:

SELECT struct_update( named_struct('name', 'Alice', 'age', 30, 'active', true), 'age', 31 ) AS updated; -- 返回:{"name":"Alice","age":31,"active":true}

struct_update
struct_update
只修改指定字段,其余字段保持不变。

嵌套 STRUCT

STRUCT 的字段类型可以是另一个 STRUCT,使用链式点符号访问嵌套字段:

SELECT named_struct( 'outer', named_struct('inner_val', 42, 'label', 'test'), 'count', 3 ) AS nested; -- 返回:{"outer":{"inner_val":42,"label":"test"},"count":3} -- 访问嵌套字段 SELECT named_struct( 'outer', named_struct('inner_val', 42, 'label', 'test'), 'count', 3 ).outer.inner_val AS deep_val; -- 返回:42

STRUCT 与 ARRAY 组合

STRUCT 常与 ARRAY 组合,用于存储结构化对象列表:

-- 构造 STRUCT 数组 SELECT ARRAY( named_struct('name', 'Alice', 'score', 95), named_struct('name', 'Bob', 'score', 87) ) AS students; -- 返回:[{"name":"Alice","score":95},{"name":"Bob","score":87}]

EXPLODE
EXPLODE
展开 STRUCT 数组,再通过字段访问提取各字段:

SELECT s.name, s.score FROM ( SELECT ARRAY( named_struct('name', 'Alice', 'score', 95), named_struct('name', 'Bob', 'score', 87) ) AS students ) t LATERAL VIEW EXPLODE(students) tmp AS s;

namescore
Alice95
Bob87

类型转换

-- 转换字段类型 SELECT CAST(named_struct('a', 1, 'b', 2) AS STRUCT<a:BIGINT, b:BIGINT>) AS cast_struct; -- 返回:{"a":1,"b":2}(字段类型变为 bigint)

CAST to STRING 与 TO_JSON 的格式区别

SELECT CAST(named_struct('name', 'Alice', 'age', 30) AS STRING); -- 返回:{Alice, 30}(只有值,无字段名,非 JSON) SELECT TO_JSON(named_struct('name', 'Alice', 'age', 30)); -- 返回:{"name":"Alice","age":30}(标准 JSON,含字段名)

NULL 处理

STRUCT 的任意字段均可为 NULL:

SELECT named_struct('name', NULL, 'age', 30) AS s; -- 返回:{"name":null,"age":30}

按结构体字段过滤时,NULL 字段参与比较会返回 NULL(不是 true 或 false):

SELECT id, person.name FROM doc_struct_demo WHERE person.age > 26; -- id=3 的 age 为 NULL,该行不出现在结果中

idname
1Alice

注意事项

  • STRUCT 支持
    =
    =
    相等比较,不支持
    >
    >
    <
    <
    等大小比较,也不支持作为 GROUP BY 键或 JOIN 键。
  • 字段名在同一 STRUCT 内必须唯一。
  • 字段名大小写不敏感,
    person.Name
    person.Name
    person.name
    person.name
    访问同一字段。
  • CAST to STRING 只输出值,不含字段名;如需含字段名的 JSON,使用
    TO_JSON
    TO_JSON

相关文档

联系我们
预约咨询
微信咨询
电话咨询