eliminate duplicate array values in postgres

GVK*_*GVK 69 postgresql

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.

mne*_*cia 72

这些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)
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建自己的功能来执行此操作

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$;
Run Code Online (Sandbox Code Playgroud)

这是一个示例调用:

SELECT array_sort_unique('{1,2,3,2,1}'::int[]);
 array_sort_unique 
-------------------
 {1,2,3}
(1 row)
Run Code Online (Sandbox Code Playgroud)

  • 问题的解决方案(“消除重复的数组值”)不需要*排序*。尽管通常是一个有用的功能,但在这种情况/要求中它是不必要的(CPU 成本)。 (3认同)

小智 72

我面对同样的事情.但我的案例中的数组是通过array_agg函数创建的.幸运的是,它允许聚合DISTINCT值,例如:

  array_agg(DISTINCT value)
Run Code Online (Sandbox Code Playgroud)

这适合我.

  • select array_agg(DISTINCT Array [1,2,2,3])给出"{{1,2,2,3}}" (4认同)
  • 请注意,窗口函数不支持DISTINCT. (3认同)
  • @user48956,这是合乎逻辑的,当您输入数组作为值时,您需要将单个列设置为查询中分组依据的值 (2认同)

Pet*_*uss 15

... 这种array_X实用程序标准(?)在哪里

尝试搜索...看到一些但没有标准:


最简单,更快速的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;
Run Code Online (Sandbox Code Playgroud)

注意:它与任何数据类型一样按预期工作,除了数组数组,

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}"
Run Code Online (Sandbox Code Playgroud)

"副作用"是爆炸一组元素中的所有数组.

PS:用JSONB数组工作正常,

SELECT array_distinct( array['[3,3]'::JSONB, '[3,3]'::JSONB, '[5,6]'::JSONB] );
 -- "{"[3, 3]","[5, 6]"}"
Run Code Online (Sandbox Code Playgroud)

编辑:更复杂但有用,"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;
Run Code Online (Sandbox Code Playgroud)


Jos*_*rns 13

我已经组装了一组存储过程(函数)来对抗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]


ale*_*sky 9

这是"内联"方式:

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;
Run Code Online (Sandbox Code Playgroud)

首先我们从数组创建一个集合,然后我们只选择不同的条目,然后将它聚合回数组.

  • 或者"更内联";-)`SELECT array_agg(DISTINCT c1)FROM unnest(ARRAY [1234,5343,6353,1234,1234])t(c1)` (8认同)

tbu*_*ann 7

使用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;
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案!另请参阅:https://dba.stackexchange.com/questions/211501/how-to-remove-duplicates-from-any-array-and-preserve-ordering-in-postgresql (2认同)

小智 6

在单个查询中,我这样做了:

SELECT (select array_agg(distinct val) from ( select unnest(:array_column) as val ) as u ) FROM :your_table;

Run Code Online (Sandbox Code Playgroud)