I have an array with duplicate values in postgres. For example:
SELECT cardinality(string_to_array('1,2,3,4,4', ',')::int[]) as foo
=> "foo"=>"5"
I would like to get unique elements, for example:
SELECT cardinality(uniq(string_to_array('1,2,3,4,4', ',')::int[])) as foo
=> -- No function matches the given name and argument types. You might need to add explicit type casts.
Can I get unique elements of an array in postgres without using UNNEST ?
Removing duplicate rows from a query result set in PostgreSQL can be done using the SELECT statement with the DISTINCT clause. It keeps one row for each group of duplicates. The DISTINCT clause can be used for a single column or for a list of columns.
In the SELECT statement, the PostgreSQL DISTINCT clause is used to delete duplicate records from a result set. For each set of duplicates, the DISTINCT clause saves one row. PostgreSQL DISTINCT eliminates all duplicate rows and keeps just one entry for each duplicated row group.
The array_unique() function removes duplicate values from an array.
I prefer this syntax (about 5% faster)
create or replace function public.array_unique(arr anyarray)
returns anyarray as $body$
select array( select distinct unnest($1) )
$body$ language 'sql';
using:
select array_unique(ARRAY['1','2','3','4','4']);
For integer arrays use intarray extension:
create extension if not exists intarray;
select cardinality(uniq(string_to_array('1,2,3,4,4', ',')::int[])) as foo
or the function
create or replace function public.array_unique(arr anyarray)
returns anyarray
language sql
as $function$
select array_agg(distinct elem)
from unnest(arr) as arr(elem)
$function$;
for any array. You can easily modify the function to preserve the original order of the array elements:
create or replace function public.array_unique_ordered(arr anyarray)
returns anyarray
language sql
as $function$
select array_agg(elem order by ord)
from (
select distinct on(elem) elem, ord
from unnest(arr) with ordinality as arr(elem, ord)
order by elem, ord
) s
$function$;
Example:
with my_data(arr) as (values ('{d,d,a,c,b,b,a,c}'::text[]))
select array_unique(arr), array_unique_ordered(arr)
from my_data
array_unique | array_unique_ordered
--------------+----------------------
{a,b,c,d} | {d,a,c,b}
(1 row)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With