Mam tablicę typu bigint
, jak mogę usunąć zduplikowane wartości w tej tablicy?
Dawny: array[1234, 5343, 6353, 1234, 1234]
Powinienem dostać array[1234, 5343, 6353, ...]
Przetestowałem przykład SELECT uniq(sort('{1,2,3,2,1}'::int[]))
w podręczniku postgres, ale nie działa.
postgresql
GVK
źródło
źródło
trim(string_agg(distinct to_char(z.dat_codigo,'0000000000'),'')) as dat_codigo,
sort(int[])
Iuniq(int[])
funkcje są dostarczane przez intarray modułu contrib.Aby móc z niego korzystać należy zainstalować moduł .
Jeśli nie chcesz używać modułu wstawiania intarray lub jeśli musisz usunąć duplikaty z tablic innego typu, masz dwa inne sposoby.
Jeśli masz przynajmniej PostgreSQL 8.4, możesz skorzystać z
unnest(anyarray)
funkcjiSELECT ARRAY(SELECT DISTINCT UNNEST('{1,2,3,2,1}'::int[]) ORDER BY 1); ?column? ---------- {1,2,3} (1 row)
Alternatywnie możesz stworzyć własną funkcję, aby to zrobić
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$;
Oto przykładowe wywołanie:
SELECT array_sort_unique('{1,2,3,2,1}'::int[]); array_sort_unique ------------------- {1,2,3} (1 row)
źródło
... Gdzie biblioteki statandard (?) Dla tego rodzaju narzędzia array_X ?
Spróbuj wyszukać ... Zobacz niektóre, ale bez standardu:
postgres.cz/wiki/Array_based_functions : dobre odniesienie!
JDBurnZ / postgresql-anyarray , dobra inicjatywa, ale wymaga współpracy, aby ją ulepszyć.
wiki.postgresql.org/Snippets , sfrustrowana inicjatywa, ale „oficjalne wiki” wymaga współpracy, aby ją ulepszyć.
MADlib : dobrze! .... ale jest to słoń, a nie „biblioteka czystych fragmentów SQL”.
Najprostsza i szybsza
array_distinct()
funkcja snippet-libTutaj najprostsza i być może szybsza implementacja dla
array_unique()
lubarray_distinct()
:CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$ SELECT array_agg(DISTINCT x) FROM unnest($1) t(x); $f$ LANGUAGE SQL IMMUTABLE;
UWAGA: działa zgodnie z oczekiwaniami z każdym typem danych, z wyjątkiem tablicy tablic,
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}"
„efektem ubocznym” jest rozbicie wszystkich tablic w zestawie elementów.
PS: z tablicami JSONB działa dobrze,
SELECT array_distinct( array['[3,3]'::JSONB, '[3,3]'::JSONB, '[5,6]'::JSONB] ); -- "{"[3, 3]","[5, 6]"}"
Edycja: bardziej złożona, ale użyteczna, parametr „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;
źródło
Zebrałem zestaw procedur składowanych (funkcji) w celu zwalczania braku obsługi tablic przez PostgreSQL
anyarray
. Te funkcje są zaprojektowane do działania z dowolnym typem danych tablicy, a nie tylko liczbami całkowitymi, jak robi to intarray: https://www.github.com/JDBurnZ/anyarrayW twoim przypadku wszystko, czego naprawdę potrzebujesz, to
anyarray_uniq.sql
. Skopiuj i wklej zawartość tego pliku do zapytania PostgreSQL i wykonaj je, aby dodać funkcję. Jeśli potrzebujesz również sortowania tablic, dodaj takżeanyarray_sort.sql
.Stamtąd możesz wykonać proste zapytanie w następujący sposób:
SELECT ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234])
Zwraca coś podobnego do:
ARRAY[1234, 6353, 5343]
Lub jeśli potrzebujesz sortowania:
SELECT ANYARRAY_SORT(ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234]))
Zwróć dokładnie:
ARRAY[1234, 5343, 6353]
źródło
Użycie
DISTINCT
niejawnie sortuje tablicę. Jeśli podczas usuwania duplikatów trzeba zachować względną kolejność elementów tablicy, funkcja może zostać zaprojektowana w następujący sposób: (powinna działać od 9.4 wzwyż)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;
źródło
Oto sposób „wbudowany”:
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;
Najpierw tworzymy zestaw z tablicy, następnie wybieramy tylko odrębne wpisy, a następnie agregujemy go z powrotem w tablicę.
źródło
SELECT array_agg(DISTINCT c1) FROM unnest(ARRAY[1234,5343,6353,1234,1234]) t(c1)
W jednym zapytaniu zrobiłem to:
SELECT (select array_agg(distinct val) from ( select unnest(:array_column) as val ) as u ) FROM :your_table;
źródło
Dla ludzi takich jak ja, którzy nadal mają do czynienia z postgres 8.2, ta rekurencyjna funkcja może wyeliminować duplikaty bez zmiany sortowania tablicy
CREATE OR REPLACE FUNCTION my_array_uniq(bigint[]) RETURNS bigint[] AS $BODY$ DECLARE n integer; BEGIN -- number of elements in the array n = replace(split_part(array_dims($1),':',2),']','')::int; IF n > 1 THEN -- test if the last item belongs to the rest of the array IF ($1)[1:n-1] @> ($1)[n:n] THEN -- returns the result of the same function on the rest of the array return my_array_uniq($1[1:n-1]); ELSE -- returns the result of the same function on the rest of the array plus the last element return my_array_uniq($1[1:n-1]) || $1[n:n]; END IF; ELSE -- if array has only one item, returns the array return $1; END IF; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE;
na przykład :
select my_array_uniq(array[3,3,8,2,6,6,2,3,4,1,1,6,2,2,3,99]);
da
źródło