[SQL] PostgreSQL의 여러 배열의 교차로
SQLPostgreSQL의 여러 배열의 교차로
내가보기로 정의가 :
CREATE VIEW View1 AS
SELECT Field1, Field2, array_agg(Field3) AS AggField
FROM Table1
GROUP BY Field1, Field2;
내가 뭘하고 싶은처럼 뭔가 AggField의 배열의 교회법을 얻을 수 있습니다 :
SELECT intersection(AggField) FROM View1 WHERE Field2 = 'SomeValue';
이 모든 가능한에, 아니면 내가 원하는 것을 달성하기 위해 더 나은 방법은 무엇입니까?
해결법
-
==============================
1.내가 생각할 수있는 배열 교차로에 가장 가까운 것은 이것이다 :
내가 생각할 수있는 배열 교차로에 가장 가까운 것은 이것이다 :
select array_agg(e) from ( select unnest(a1) intersect select unnest(a2) ) as dt(e)
이것은 그 A1 및 A2지지 요소의 동일한 유형의 단일 차원 배열이다. 이 같은 기능 뭔가 그것을 마무리 수 :
create function array_intersect(a1 int[], a2 int[]) returns int[] as $$ declare ret int[]; begin -- The reason for the kludgy NULL handling comes later. if a1 is null then return a2; elseif a2 is null then return a1; end if; select array_agg(e) into ret from ( select unnest(a1) intersect select unnest(a2) ) as dt(e); return ret; end; $$ language plpgsql;
그럼 당신은 이런 일을 할 수 있습니다 :
=> select array_intersect(ARRAY[2,4,6,8,10], ARRAY[1,2,3,4,5,6,7,8,9,10]); array_intersect ----------------- {6,2,4,10,8} (1 row)
참고이 반환 된 배열에 특정 순서를 보장하지 않습니다하지만 당신은 당신이 그것에 대해 걱정하는 경우 있음을 해결할 수 있습니다. 그런 다음 당신은 당신의 자신의 집계 함수를 만들 수 있습니다 :
-- Pre-9.1 create aggregate array_intersect_agg( sfunc = array_intersect, basetype = int[], stype = int[], initcond = NULL ); -- 9.1+ (AFAIK, I don't have 9.1 handy at the moment -- see the comments below. create aggregate array_intersect_agg(int[]) ( sfunc = array_intersect, stype = int[] );
그리고 지금 우리는 array_intersect가 null로 재미와 약간 kludgey 일을하는 이유를 참조하십시오. 우리는 전체 집합처럼 동작합니다 우리가 그것에 대해 NULL을 사용할 수는있는 통합에 대한 초기 값이 필요 (예,이 떨어져 조금 냄새를하지만 난 내 머리 위로 떨어져 더 나은 아무것도 생각할 수 없다).
이 모든 장소에 있으면,이 같은 일을 할 수있다 :
> select * from stuff; a --------- {1,2,3} {1,2,3} {3,4,5} (3 rows) > select array_intersect_agg(a) from stuff; array_intersect_agg --------------------- {3} (1 row)
아니 정확히 단순 또는 효율적인하지만 어쩌면 합리적인 시작점과 전혀 아무것도보다 낫다.
유용한 참조 :
-
==============================
2.허용 대답은 나를 위해 작동하지 않았다. 이것은 내가 그것을 해결하는 방법입니다.
허용 대답은 나를 위해 작동하지 않았다. 이것은 내가 그것을 해결하는 방법입니다.
create or replace function array_intersect(a1 int[], a2 int[]) returns int[] as $$ declare ret int[]; begin -- RAISE NOTICE 'a1 = %', a1; -- RAISE NOTICE 'a2 = %', a2; if a1 is null then -- RAISE NOTICE 'a1 is null'; return a2; -- elseif a2 is null then -- RAISE NOTICE 'a2 is null'; -- return a1; end if; if array_length(a1,1) = 0 then return '{}'::integer[]; end if; select array_agg(e) into ret from ( select unnest(a1) intersect select unnest(a2) ) as dt(e); if ret is null then return '{}'::integer[]; end if; return ret; end; $$ language plpgsql;
-
==============================
3.그것은이 질문에 대한 답을 조금 늦게하지만 난 원인은 배열의 숫자의 교차로에 대한 모든 준비가 해결책을 발견하지 않았다 썼다 주 뭔가하기로 결정 그래서 아마 누군가가 필요합니다. 그래서 여기 있습니다. 더 그 2 개 배열 인 경우 2 개 어레이는 2 개 어레이 및 리턴 결과 교차가 존재 함수 인 경우 단지 하나의 배열, 함수 반환 제 배열 인 경우,이 함수는, 배열의 어레이를 수신하고, 함수는 점포를 2 개 제 배열 교차 소요 다른 모든 배열을 통해 어떤 변수 및 루프에 저장된 결과 다음의 각 배열을 교차 저장 변수 초래한다. 결과가 null 인 경우는 null를 존재한다. 앤드 상호 작용 된 데이터를 저장하는 배열 함수로부터 반환되는 변수.
그것은이 질문에 대한 답을 조금 늦게하지만 난 원인은 배열의 숫자의 교차로에 대한 모든 준비가 해결책을 발견하지 않았다 썼다 주 뭔가하기로 결정 그래서 아마 누군가가 필요합니다. 그래서 여기 있습니다. 더 그 2 개 배열 인 경우 2 개 어레이는 2 개 어레이 및 리턴 결과 교차가 존재 함수 인 경우 단지 하나의 배열, 함수 반환 제 배열 인 경우,이 함수는, 배열의 어레이를 수신하고, 함수는 점포를 2 개 제 배열 교차 소요 다른 모든 배열을 통해 어떤 변수 및 루프에 저장된 결과 다음의 각 배열을 교차 저장 변수 초래한다. 결과가 null 인 경우는 null를 존재한다. 앤드 상호 작용 된 데이터를 저장하는 배열 함수로부터 반환되는 변수.
CREATE OR REPLACE FUNCTION array_intersected(iarray bigint[][]) RETURNS bigint[] AS $BODY$ declare out_arr bigint[]; set1 bigint[]; set2 bigint[]; BEGIN --RAISE NOTICE '%', array_length(iarray, 1); if array_length(iarray, 1) = 1 then SELECT ARRAY(SELECT unnest(iarray[1:1])) into out_arr; elseif array_length( iarray, 1) = 2 then set1 := iarray[1:1]; set2 := iarray[2:2]; SELECT ARRAY(SELECT unnest(set1) INTERSECT SELECT unnest(set2))into out_arr; elseif array_length(iarray, 1) > 2 then set1 := iarray[1:1]; set2 := iarray[2:2]; --exit if no common numbers exists int 2 first arrays SELECT ARRAY(SELECT unnest(set1) INTERSECT SELECT unnest(set2))into out_arr; if out_arr = NULL then EXIT; END IF; FOR i IN 3 .. array_upper(iarray, 1) LOOP set1 := iarray[i:i]; SELECT ARRAY(SELECT unnest(set1) INTERSECT SELECT unnest(out_arr))into out_arr; if out_arr = NULL then EXIT; END IF; END LOOP; end if; return out_arr; END; $BODY$ LANGUAGE plpgsql VOLATILE;
여기에 작동의 유효성을 검사하는 코드입니다.
select array_intersected(array[[1, 2]]::bigint[][]); select array_intersected(array[[1, 2],[2, 3]]::bigint[][]); select array_intersected(array[[1, 2],[2, 3], [2, 4]]::bigint[][]); select array_intersected(array[[1, 2, 3, 4],[null, null, 4, 3], [3, 1, 4, null]]::bigint[][]);
from https://stackoverflow.com/questions/7020264/intersection-of-multiple-arrays-in-postgresql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 합니까 오라클 롤 오류에 트랜잭션을? (0) | 2020.07.08 |
---|---|
[SQL] 어떻게 PHP :: PDO를 사용하여 변수 MySQL의 스크립트를 실행하려면? (0) | 2020.07.08 |
[SQL] 데이터베이스의 각 테이블의 처음 3 개 행을 선택 (0) | 2020.07.08 |
[SQL] 열 절에 하위 쿼리와 MS SQL 서버 피벗 테이블 (0) | 2020.07.08 |
[SQL] 어떻게 내 기본 키를 선택? (0) | 2020.07.08 |