首页/数据/SQL 速查/jsonb_array_elements 展开数组(PostgreSQL)
函数速查60 条

jsonb_array_elements 展开数组(PostgreSQL)

PostgreSQL 把 JSON 数组展开成多行的惯用函数族:可带文本版本与序号,是处理 JSON 明细的基础操作。

SQL 速查数据更新于 2026-10-13

jsonb_array_elements 是什么

jsonb_array_elements(jsonb) 是 PostgreSQL 的集合返回函数:把 JSON 数组展开成多行,每行是一个元素(类型仍是 jsonb),写在 FROM 里并配合 LATERAL 语义就能逐行关联主表。另有 jsonb_array_elements_text 直接返回 text,省掉 ->> 转换;加 WITH ORDINALITY 还能附带元素序号。它是 PostgreSQL 展开 JSON 数组的标准手段,对应 MySQL 的 JSON_TABLE。

基本信息

适用平台PostgreSQL 9.4+
jsonb_array_elements返回 setof jsonb,元素继续保持 JSON 类型
jsonb_array_elements_text返回 setof text,可直接比较与拼接
WITH ORDINALITY追加序号列,从 1 开始,可用于保留数组顺序
参数不是数组报错 cannot extract elements from a non-array
与 MySQL 对应JSON_TABLE

典型使用场景

  • 展开订单商品数组,按商品维度统计销量
  • 展开标签数组做关联查询与反向筛选
  • 展开埋点参数做维度聚合
  • 统计数组元素数量、按位置取特定元素
  • 与主表连接取维度名称等补充信息
  • 统计元素为空的记录:先算数组长度,再找出长度为 0 的行

基础展开

基础展开
-- 每行一个元素
SELECT value FROM jsonb_array_elements('[{"sku":"A1"},{"sku":"B2"}]'::jsonb) AS value;

-- 展开并带序号
SELECT elem, ord
FROM jsonb_array_elements('[10,20,30]'::jsonb) WITH ORDINALITY AS t(elem, ord);

-- 直接取 text,用于比较与字符串聚合
SELECT value FROM jsonb_array_elements_text('["vip","new"]'::jsonb) AS value;

与主表逐行关联

与主表逐行关联
-- FROM 中的函数隐含 LATERAL 语义,可以直接引用左侧表的列
SELECT o.id, item->>'sku' AS sku, (item->>'qty')::int AS qty
FROM orders o,
     jsonb_array_elements(o.items) AS item
WHERE o.id = 100;

-- 展开后聚合,统计每个 sku 的总数量
SELECT item->>'sku' AS sku, sum((item->>'qty')::int) AS total_qty
FROM orders o,
     jsonb_array_elements(o.items) AS item
GROUP BY 1
ORDER BY total_qty DESC;

函数与用途对照

写法返回典型用途
jsonb_array_elementssetof jsonb还要继续用 JSON 操作符取值
jsonb_array_elements_textsetof text直接比较、拼接与字符串聚合
WITH ORDINALITY追加序号列保留数组顺序、定位元素位置
LATERAL 关联每行展开一次与主表明细一起输出
jsonb_array_length整数只想知道元素个数,不必展开
只想判断数组长度时用 jsonb_array_length 即可,不必展开;展开的动作会按元素个数放大行数,是后续聚合口径出错的主要来源。
列里的值不是数组时会直接报 cannot extract elements from a non-array:线上语句应先用 jsonb_typeof 判断类型分支,再决定是否展开,避免个别脏数据中断整个查询。
展开后的行没有隐含顺序:需要保持数组原有次序时必须加 WITH ORDINALITY 并在外层按序号排序,否则输出顺序取决于执行计划,多次查询可能不同。

易错点

  • 忘记写与主表的连接条件,展开结果与主表形成笛卡尔积
  • 展开后直接 COUNT(*) 统计主表行数,得到的是元素总数
  • 对可能不是数组的列直接展开,遇到对象或标量时报错中断
  • 混用 -> 与 ->> 取元素,得到的分别是 JSON 类型与字符串,比较结果不符合预期

数据来源与参考

  • PostgreSQL Documentation · JSON Functions and Operators
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌