Ich habe ein Array vom Typ bigint
. Wie kann ich die doppelten Werte in diesem Array entfernen?
Ex: array[1234, 5343, 6353, 1234, 1234]
Ich sollte bekommen array[1234, 5343, 6353, ...]
Ich habe das Beispiel SELECT uniq(sort('{1,2,3,2,1}'::int[]))
im Postgres-Handbuch getestet, aber es funktioniert nicht.
postgresql
GVK
quelle
quelle
trim(string_agg(distinct to_char(z.dat_codigo,'0000000000'),'')) as dat_codigo,
Die Funktionen
sort(int[])
unduniq(int[])
werden vom Intarray Contrib- Modul bereitgestellt .Um die Verwendung zu aktivieren, müssen Sie das Modul installieren .
Wenn Sie das Intarray-Contrib-Modul nicht verwenden möchten oder Duplikate aus Arrays unterschiedlichen Typs entfernen müssen, haben Sie zwei andere Möglichkeiten.
Wenn Sie mindestens PostgreSQL 8.4 haben, können Sie die
unnest(anyarray)
Funktion nutzenSELECT ARRAY(SELECT DISTINCT UNNEST('{1,2,3,2,1}'::int[]) ORDER BY 1); ?column? ---------- {1,2,3} (1 row)
Alternativ können Sie dazu eine eigene Funktion erstellen
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$;
Hier ist ein Beispielaufruf:
SELECT array_sort_unique('{1,2,3,2,1}'::int[]); array_sort_unique ------------------- {1,2,3} (1 row)
quelle
... wo die statandard Bibliotheken (?) Für diese Art von array_X Dienstprogramm ?
Versuchen Sie zu suchen ... Sehen Sie einige, aber keinen Standard:
postgres.cz/wiki/Array_based_functions : gute Referenz!
JDBurnZ / postgresql-anyarray , gute Initiative, braucht aber eine gewisse Zusammenarbeit, um sie zu verbessern.
wiki.postgresql.org/Snippets , frustrierte Initiative, aber "offizielles Wiki", braucht eine gewisse Zusammenarbeit, um sie zu verbessern.
MADlib : gut! .... aber es ist ein Elefant, keine "reine SQL-Snippets-Bibliothek".
Einfachste und schnellere
array_distinct()
Snippet-Lib-FunktionHier die einfachste und vielleicht schnellere Implementierung für
array_unique()
oderarray_distinct()
:CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$ SELECT array_agg(DISTINCT x) FROM unnest($1) t(x); $f$ LANGUAGE SQL IMMUTABLE;
HINWEIS: Es funktioniert wie erwartet mit jedem Datentyp, außer mit Arrays von Arrays.
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}"
Der "Nebeneffekt" besteht darin, alle Arrays in einer Reihe von Elementen zu explodieren.
PS: mit JSONB-Arrays funktioniert gut,
SELECT array_distinct( array['[3,3]'::JSONB, '[3,3]'::JSONB, '[5,6]'::JSONB] ); -- "{"[3, 3]","[5, 6]"}"
Bearbeiten: komplexer, aber nützlich, ein "drop nulls" -Parameter
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;
quelle
Ich habe eine Reihe gespeicherter Prozeduren (Funktionen) zusammengestellt, um den Mangel an geprägtem Array-Handling von PostgreSQL zu bekämpfen
anyarray
. Diese Funktionen funktionieren für jeden Array-Datentyp, nicht nur für Ganzzahlen wie bei Intarray: https://www.github.com/JDBurnZ/anyarrayIn Ihrem Fall ist alles, was Sie wirklich brauchen würden
anyarray_uniq.sql
. Kopieren Sie den Inhalt dieser Datei, fügen Sie ihn in eine PostgreSQL-Abfrage ein und führen Sie ihn aus, um die Funktion hinzuzufügen. Wenn Sie auch eine Array-Sortierung benötigen, fügen Sie ebenfalls hinzuanyarray_sort.sql
.Von dort aus können Sie eine einfache Abfrage wie folgt durchführen:
SELECT ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234])
Gibt etwas Ähnliches zurück wie:
ARRAY[1234, 6353, 5343]
Oder wenn Sie sortieren müssen:
SELECT ANYARRAY_SORT(ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234]))
Rückgabe genau:
ARRAY[1234, 5343, 6353]
quelle
Mit wird
DISTINCT
das Array implizit sortiert. Wenn die relative Reihenfolge der Array-Elemente beim Entfernen von Duplikaten beibehalten werden muss, kann die Funktion wie folgt gestaltet werden: (sollte ab 9.4 funktionieren)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;
quelle
Hier ist der "Inline" Weg:
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;
Zuerst erstellen wir eine Menge aus einem Array, dann wählen wir nur bestimmte Einträge aus und aggregieren sie dann wieder zu einem Array.
quelle
SELECT array_agg(DISTINCT c1) FROM unnest(ARRAY[1234,5343,6353,1234,1234]) t(c1)
In einer einzigen Abfrage habe ich Folgendes getan:
SELECT (select array_agg(distinct val) from ( select unnest(:array_column) as val ) as u ) FROM :your_table;
quelle
Für Leute wie mich, die sich noch mit Postgres 8.2 beschäftigen müssen, kann diese rekursive Funktion Duplikate beseitigen, ohne die Sortierung des Arrays zu ändern
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;
zum Beispiel :
select my_array_uniq(array[3,3,8,2,6,6,2,3,4,1,1,6,2,2,3,99]);
wird geben
quelle