I have an array of type bigint
, how can I remove the duplicate values in that array?
Ex: array[1234, 5343, 6353, 1234, 1234]
I should get array[1234, 5343, 6353, ...]
I tested out the example SELECT uniq(sort('{1,2,3,2,1}'::int[]))
in the postgres manual but it is not working.
这些sort(int[])
和uniq(int[])
函数由intarray contrib模块提供.
要启用它,您必须通过执行postgresql安装的contrib目录中的_int.sql文件来注册模块.
在Debian/Ubuntu系统上,你必须安装postgresql-contrib-8.4包,然后该文件将在/usr/share/postgresql/8.4/contrib/_int.sql下(版本号可能不同)
如果您不想使用intarray contrib模块,或者您必须从不同类型的数组中删除重复项,则还有其他两种方法.
如果你至少有PostgreSQL 8.4,你可以利用unnest(anyarray)
功能
SELECT ARRAY(SELECT DISTINCT UNNEST('{1,2,3,2,1}'::int[]) ORDER BY 1); ?column? ---------- {1,2,3} (1 row)
或者,您可以创建自己的功能来执行此操作
CREATE OR REPLACE FUNCTION array_sort_unique (ANYARRAY) RETURNS ANYARRAY LANGUAGE SQL AS $body$ SELECT ARRAY( SELECT DISTINCT $1[s.i] FROM generate_series(array_lower($1,1), array_upper($1,1)) AS s(i) ORDER BY 1 ); $body$;
这是一个示例调用:
SELECT array_sort_unique('{1,2,3,2,1}'::int[]); array_sort_unique ------------------- {1,2,3} (1 row)
我面对同样的事情.但我的案例中的数组是通过array_agg
函数创建的.幸运的是,它允许聚合DISTINCT值,例如:
array_agg(DISTINCT value)
这适合我.
... 这种array_X实用程序的标准库(?)在哪里?
尝试搜索...看到一些但没有标准:
postgres.cz/wiki/Array_based_functions:很好的参考!
JDBurnZ/postgresql-anyarray,很好的主动但需要一些协作来增强.
wiki.postgresql.org/Snippets,沮丧的倡议,但"官方维基",需要一些协作来增强.
MADlib:好!....但它是一头大象,而不是一个"纯SQL片段库".
array_distinct()
snippet-lib功能这里最简单的,也许更快的实现array_unique()
或array_distinct()
:
CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$ SELECT array_agg(DISTINCT x) FROM unnest($1) t(x); $f$ LANGUAGE SQL IMMUTABLE;
注意:它与任何数据类型一样按预期工作,除了数组数组,
SELECT array_distinct( array[3,3,8,2,6,6,2,3,4,1,1,6,2,2,3,99] ), array_distinct( array['3','3','hello','hello','bye'] ), array_distinct( array[array[3,3],array[3,3],array[3,3],array[5,6]] ); -- "{1,2,3,4,6,8,99}", "{3,bye,hello}", "{3,5,6}"
"副作用"是爆炸一组元素中的所有数组.
PS:用JSONB数组工作正常,
SELECT array_distinct( array['[3,3]'::JSONB, '[3,3]'::JSONB, '[5,6]'::JSONB] ); -- "{"[3, 3]","[5, 6]"}"
编辑:更复杂但有用,"drop nulls"参数
CREATE FUNCTION array_distinct( anyarray, -- input array boolean DEFAULT false -- flag to ignore nulls ) RETURNS anyarray AS $f$ SELECT array_agg(DISTINCT x) FROM unnest($1) t(x) WHERE CASE WHEN $2 THEN x IS NOT NULL ELSE true END; $f$ LANGUAGE SQL IMMUTABLE;
我已经组装了一组存储过程(函数)来对抗PostgreSQL缺乏创建的数组处理anyarray
.这些函数设计用于跨任何数组数据类型,而不仅仅是像inarray那样的整数:https://www.github.com/JDBurnZ/anyarray
在你的情况下,你真正需要的只是anyarray_uniq.sql
.将该文件的内容复制并粘贴到PostgreSQL查询中并执行它以添加该功能.如果您还需要数组排序,也可以添加anyarray_sort.sql
.
从那里,您可以执行如下简单查询:
SELECT ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234])
返回类似于: ARRAY[1234, 6353, 5343]
或者如果您需要排序:
SELECT ANYARRAY_SORT(ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234]))
准确地回复: ARRAY[1234, 5343, 6353]
这是"内联"方式:
SELECT 1 AS anycolumn, ( SELECT array_agg(c1) FROM ( SELECT DISTINCT c1 FROM ( SELECT unnest(ARRAY[1234,5343,6353,1234,1234]) AS c1 ) AS t1 ) AS t2 ) AS the_array;
首先我们从数组创建一个集合,然后我们只选择不同的条目,然后将它聚合回数组.
使用DISTINCT
隐式对数组进行排序。如果在删除重复项时需要保留数组元素的相对顺序,则可以将函数设计如下:(应从9.4开始工作)
CREATE OR REPLACE FUNCTION array_uniq_stable(anyarray) RETURNS anyarray AS $body$ SELECT array_agg(distinct_value ORDER BY first_index) FROM (SELECT value AS distinct_value, min(index) AS first_index FROM unnest($1) WITH ORDINALITY AS input(value, index) GROUP BY value ) AS unique_input ; $body$ LANGUAGE 'sql' IMMUTABLE STRICT;