postgres에서 중복 배열 값 제거
유형의 배열이 bigint
있습니다. 해당 배열에서 중복 값을 제거하려면 어떻게해야합니까?
전의: array[1234, 5343, 6353, 1234, 1234]
나는 얻어야한다 array[1234, 5343, 6353, ...]
SELECT uniq(sort('{1,2,3,2,1}'::int[]))
postgres 매뉴얼에서 예제 를 테스트 했지만 작동하지 않습니다.
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 유틸리티를 위한 statandard 라이브러리 (?)는 어디에 있습니까 ?
검색해보십시오 ... 표준은 아니지만 일부보기 :
postgres.cz/wiki/Array_based_functions : 좋은 참조입니다!
JDBurnZ / postgresql-anyarray , 좋은 이니셔티브이지만 개선하려면 일부 협력이 필요합니다.
wiki.postgresql.org/Snippets , 실망스러운 이니셔티브이지만 "공식 위키"는 향상시키기 위해 약간의 협력이 필요합니다.
MADlib : 좋아요! .... 그러나 이것은 "순수 SQL 스 니펫 라이브러리"가 아니라 코끼리입니다.
가장 간단하고 빠른 array_distinct()
snippet-lib 함수
여기에 array_unique()
or에 대한 가장 간단하고 빠른 구현이 있습니다 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}"
"부작용"은 요소 집합의 모든 배열을 분해하는 것입니다.
추신 : 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
. 이 함수는 intarray처럼 정수뿐만 아니라 모든 배열 데이터 유형에서 작동하도록 설계되었습니다 : 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;
먼저 배열에서 집합을 만든 다음 고유 항목 만 선택한 다음 다시 배열로 집계합니다.
Using DISTINCT
implicitly sorts the array. If the relative order of the array elements needs to be preserved while removing duplicates, the function can be designed like the following: (should work from 9.4 onwards)
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;
For people like me who still have to deal with postgres 8.2, this recursive function can eliminate duplicates without altering the sorting of the array
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;
for exemple :
select my_array_uniq(array[3,3,8,2,6,6,2,3,4,1,1,6,2,2,3,99]);
will give
{3,8,2,6,4,1,99}
One of possible variant
UPDATE table SET array_column = uniq(array_column)
참고URL : https://stackoverflow.com/questions/3994556/eliminate-duplicate-array-values-in-postgres
'UFO ET IT' 카테고리의 다른 글
jQuery에 대한 요소 또는 클래스 LIKE 선택기? (0) | 2020.11.09 |
---|---|
코드에 주석을 달지 않고 어떻게 vim으로 붙여 넣습니까? (0) | 2020.11.09 |
C # 비트 맵에 텍스트 쓰기 (0) | 2020.11.09 |
지원 벡터의 수와 훈련 데이터 및 분류기 성능 간의 관계는 무엇입니까? (0) | 2020.11.09 |
Facebook 좋아요 상자를 반응 형으로 만드는 방법은 무엇입니까? (0) | 2020.11.09 |