You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL中用UNNEST和JOIN生成数组列?

PostgreSQL 将ID数组转换为对应名称数组的解决方案

在PostgreSQL中没有Oracle类似的NEST函数,但可以通过array_agg()函数实现将分组后的行数据重新聚合为数组的需求,核心是要保留原数组的顺序,否则聚合结果会不符合预期。

方法一:基于你已有的UNNEST查询改造

在拆分数组并关联名称表后,结合原数组的下标排序来聚合名称:

SELECT 
  ww.widget_id,
  array_agg(n.naam ORDER BY ww.name_id_pos) AS names
FROM (
  SELECT 
    widget_id,
    unnest(name_ids) AS name_id,
    -- 获取原数组中元素的位置,用于后续排序保证顺序
    generate_subscripts(name_ids, 1) AS name_id_pos
  FROM widgets
) ww
INNER JOIN names n ON ww.name_id = n.name_id
GROUP BY ww.widget_id
ORDER BY ww.widget_id;

方法二:使用横向连接(JOIN LATERAL)+ UNNEST WITH ORDINALITY

PostgreSQL 9.4及以上版本支持unnest ... WITH ORDINALITY语法,可直接获取数组元素及其在原数组中的位置,写法更简洁:

SELECT 
  w.widget_id,
  -- 按原数组的位置排序后聚合
  array_agg(n.naam ORDER BY u.ordinality) AS names
FROM widgets w
-- 横向连接拆分数组,同时获取元素位置
JOIN LATERAL unnest(w.name_ids) WITH ORDINALITY u(name_id) ON true
JOIN names n ON u.name_id = n.name_id
GROUP BY w.widget_id
ORDER BY w.widget_id;

关键注意点

如果省略ORDER BY子句,array_agg()会默认按聚合字段(此处为naam)的字母顺序排列,导致widget_id=2的结果变成{Bo,Che},不符合预期。通过generate_subscripts或ordinality获取原数组的位置并排序,才能保证结果数组的顺序和原name_ids完全一致。

执行结果

上述两种方法都会得到你期望的输出:

widget_id|names      |
---------+-----------+
        1|{Ad,Bo,Che}|
        2|{Che,Bo}   |

内容的提问来源于stack exchange,提问作者Roland Kwee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:51:01