sybn sybn-util 项目说明文档 - 基于java的跨数据库联合查询

unnest / unwind 将数组/Map 列拆分为多行

2026-05-20
sybn
sql

  • content

说明

unnest 和 unwind 都是列转行命令,用于将数组或 Map 类型的字段拆分成多行,其余字段复制到每一行。

命令 语法风格 来源
unwind unwind(字段1, 字段2, ...) 类似 MongoDB 的 unwind
unnest UNNEST(字段) as t(字段1, 字段2) 类似 Flink/PG 的 unnest

两者的核心区别:

  • unwind 可以同时拆分多个字段,做笛卡尔积。
  • unnest 一次拆分一个字段,但可以自定义输出列名。

unwind 语法

select unwind(字段1, 字段2, ...) from ...
-- 或作为后置命令
select ...; unwind(字段1, 字段2, ...)

拆分数组

-- 把 b 字段(数组)拆成两行,a 字段复制到每一行
select * from [{'a':1, 'b':['b1','b2']}];
-- 结果:[{a:1, b:'b1'}, {a:1, b:'b2'}]
-- 也可以在 select 中直接用 unwind
select unwind(b) b from [{'a':1, 'b':['b1','b2']}];
-- 结果:[{a:1, b:'b1'}, {a:1, b:'b2'}]

多字段拆分(笛卡尔积)

-- 同时拆分 b 和 c,做笛卡尔积
select * from [{'a':1, 'b':['b1','b2'], 'c':['c1','c2','c3']}];
unwind(b, c);
-- 结果:6 行(2×3 笛卡尔积)
-- [{a:1,b:'b1',c:'c1'}, {a:1,b:'b1',c:'c2'}, {a:1,b:'b1',c:'c3'},
--  {a:1,b:'b2',c:'c1'}, {a:1,b:'b2',c:'c2'}, {a:1,b:'b2',c:'c3'}]

拆分逗号分隔字符串

-- 用 toList 把字符串转成数组再 unwind
select unwind(toList(b)) b from [{'a':1, 'b':'b1,b2'}];
-- 结果:[{a:1, b:'b1'}, {a:1, b:'b2'}]

拆分 Map

-- 把 Map 拆成 key/value 两列
select * from [{'a':1, 'b':{'x':1, 'y':2}}];
unwind(b);
-- 结果:[{a:1, b_key:'x', b_value:1}, {a:1, b_key:'y', b_value:2}]

unnest 语法

select ... from UNNEST(字段) as t(列名1, 列名2)
  • 字段:要拆分的 Map 或数组字段名(可用反引号包裹)。
  • t:别名(可省略)。
  • 列名1, 列名2:拆分后的输出列名。
    • 拆 Map 时:第一个列名对应 key,第二个对应 value。
    • 拆数组时:第一个列名对应数组元素。

例子

-- 拆分 Map,输出 mapKey 和 mapValue 两列
select * from UNNEST(pageInfo) as t(mapKey, mapValue);
-- 格式化后:unnest(pageInfo) as t(`mapKey` AS mapKey, `mapValue` AS mapValue)
-- 不加反引号也可以
select * from UNNEST(pageInfo) as t(mapKey, mapValue);
-- 格式化后:unnest(pageInfo) as t(mapKey, mapValue)

注意事项

  1. unwind 可以同时拆多个字段做笛卡尔积,unnest 一次只拆一个。
  2. unwind 拆 Map 时输出列名固定为 字段_key 和 字段_value;unnest 可以自定义列名。
  3. unwind 可以在 select 字段列表中使用(select unwind(b) b),也可以作为后置命令。
  4. 如果字段不是数组/Map,unwind 会先用 toList 尝试转换(如把逗号字符串转数组)。

Comments

暂不开放评论! 可微信联系