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

PostgreSQL同长度数组列调用unnest表函数的非预期行为问题

我原本认为使用表函数时,会为当前行生成关联的新行,每个新行可包含多列,每列存储所引用表达式基于当前行求值得到的单个值。

文字表述可能较为冗长且不够清晰,可运行如下示例,查看结果行中数组元素的组合规则:

测试语句1:

select 
    id,    
    unnest(numbers),
    unnest(letters)
  from
  (
    values
    (1, ARRAY[1,2], ARRAY['a','b', 'c']),
    (2, ARRAY[3,4], ARRAY['d','e', 'f'])
  ) as aTable(id,numbers,letters)

运行该语句时,数据库会逐行将数组视为集合,生成类笛卡尔积的组合结果。

测试语句2:

select 
    id,    
    unnest(numbers),
    unnest(letters)
  from
  (
    values
    (1, ARRAY[1,2], ARRAY['a','b']),
    (2, ARRAY[3,4], ARRAY['d','e'])
  ) as aTable(id,numbers,letters)

该语句中两个入参数组长度完全一致,我本预期会得到和上一个示例相同的笛卡尔积结果,但实际输出采用了不同的组合规则。经同事提醒,该现象可能与参与运算的数组长度相同有关。我查阅了PostgreSQL 14官方文档中表表达式章节的表函数相关内容,未找到对应规则说明,希望了解该现象的底层逻辑,以及如何在数组等长场景下强制生成笛卡尔积结果。

更新(收到Laurenz的答复后补充)

若要实现数组元素的全量笛卡尔积组合,可将表函数移入FROM子句,通过lateral join实现,参考语句如下:

select id,number,letter
  from
  (
    values
    (1, ARRAY[1,2], ARRAY['a','b']),
    (2, ARRAY[3,4], ARRAY['d','e'])
  ) as aTable(id,numbers,letters)
  cross join lateral unnest(numbers) as number
  cross join lateral unnest(letters) as letter

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:27:20