postgresql原生不提供array_remove函数;需用unnest+where+array()组合实现移除,或创建自定义函数并用is distinct from安全处理null,但仅适用于一维数组。

PostgreSQL 没有 ARRAY_REMOVE 函数
直接说结论:PostgreSQL 原生不提供 ARRAY_REMOVE 函数。你执行 SELECT ARRAY_REMOVE(ARRAY[1,2,2,3], 2); 会报错 ERROR: function array_remove(integer[], integer) does not exist。这不是拼写或版本问题——它真不存在,哪怕在 PostgreSQL 16 里也没有。
用 ARRAY() + SELECT WHERE 实现等效移除
最可靠、兼容性最好的方式是把数组展开成行,过滤后再聚合成新数组。核心思路是:用 UNNEST 打散 → WHERE 排除目标值 → ARRAY() 重建。
示例:移除整数数组中所有 2
SELECT ARRAY( SELECT x FROM UNNEST(ARRAY[1,2,2,3]) AS x WHERE x != 2 );
返回 {1,3}。注意几点:
-
UNNEST后必须用别名(如AS x),否则WHERE无法引用 - 若原数组含
NULL,x != 2不会匹配NULL(因为NULL != 2结果为NULL,被当作假),需显式写WHERE x != 2 OR x IS NULL来保留NULL,或用WHERE COALESCE(x != 2, true)—— 取决于你是否想删NULL - 该方法保持原始顺序,不改变重复元素的相对位置
用自定义函数封装(适合高频使用)
如果项目里频繁需要“移除数组元素”,可以建一个轻量函数避免重复写 UNNEST + ARRAY()。例如:
CREATE OR REPLACE FUNCTION array_remove(anyarray, anyelement)
RETURNS anyarray AS $$
SELECT ARRAY(
SELECT $1[i]
FROM generate_subscripts($1, 1) AS i
WHERE $1[i] IS DISTINCT FROM $2
);
$$ LANGUAGE sql IMMUTABLE;
用法:SELECT array_remove(ARRAY[1,2,NULL,2], 2); → {1,NULL}。关键点:
- 用
IS DISTINCT FROM而非!=,才能正确处理NULL元素(NULL IS DISTINCT FROM NULL为假,即保留原NULL;NULL IS DISTINCT FROM 2为真,即移除) -
generate_subscripts避开了UNNEST对多维数组或空数组的潜在歧义,更贴近“按索引过滤”的直觉 - 函数标为
IMMUTABLE,允许在索引表达式或分区键中使用
注意多维数组和嵌套结构的边界情况
上述方法都只作用于一维数组。如果你传入二维数组(如 ARRAY[[1,2],[3,4]]),UNNEST 会完全展平成一维({1,2,3,4}),而 generate_subscripts 版本则按第一维索引遍历,$1[i] 取出的是子数组(如 ARRAY[1,2]),此时比较 $1[i] IS DISTINCT FROM $2 就是在比整个子数组——这往往不是你想要的。
真正要删除二维数组中的某个“行”,得明确写成:
SELECT ARRAY(
SELECT arr FROM (
SELECT unnest(ARRAY[ARRAY[1,2], ARRAY[3,4]]) AS arr
) t WHERE arr != ARRAY[1,2]
);
也就是说:没有银弹。数组维度、元素类型、是否含 NULL、是否要保留空数组,都会影响具体写法。别依赖“通用函数”自动适配所有场景。










