Postgres 배열에 값이 있는지 확인


196

Postgres 9.0을 사용하여 주어진 배열에 값이 있는지 테스트하는 방법이 필요합니다. 지금까지 나는 다음과 같은 것을 생각해 냈습니다.

select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)

그러나 나는 이것에 대한 더 간단한 방법이 있어야한다고 생각합니다. 나는 그것을 볼 수 없습니다. 이것은 더 좋아 보인다 :

select '{1,2,3}'::int[] @> ARRAY[value_variable::int]

나는 그것이 충분할 것이라고 믿는다. 그러나 다른 방법이 있다면 공유하십시오!

답변:


323

구조가 더 간단합니다 ANY.

SELECT value_variable = ANY ('{1,2,3}'::int[])

ANY(괄호 사이 의) 오른쪽 피연산자는 집합 (예 : 하위 쿼리의 결과) 이거나 배열 일 수 있습니다. 여러 가지 방법으로 사용할 수 있습니다.

중요한 차이 : (배열 연산자 <@, @>, &&. 등) 예상 배열 피연산자와 같은 유형의 지지 진 또는 GIST 인덱스 그동안, PostgreSQL의 표준 분포를 ANY구조가 예상 소자 피연산자 좌측 이러한 인덱스를 지원하지 않는 타입. 예:

이 중 어느 것도 NULL요소에 적용되지 않습니다. 테스트하려면 NULL:


감사. 매뉴얼의 해당 부분을 건너 뛰었을 것입니다. 이것은 잘 작동합니다. 자동 주조의 부작용이 있습니다. 예 : SELECT 1 :: smallint = ANY ( '{1,2,3}':: int []) 작동합니다. 표현식의 오른쪽에 ANY ()를 넣으십시오.
Mike Starov 2016 년

답변 해주셔서 감사합니다. 내 쿼리가 로컬에서 작동하는 문제가 있지만 heroku 에서이 메시지를 던지면서 매력 ANY/ALL (array) requires array on right side이 추가되었습니다 ::int[].
kinduff December

여기서 S.employee_id <@ ANY ( ' "+ employeeIDsArray +"':: int []) PSQLException을 반환합니다. ERROR : 치수 값 누락
Ramprasad

3
이것은 인터넷 시대의 공룡 질문이지만 저와 같은 느린 사람들 'something' = ANY(some_array)WHERE절 에서도 사용될 수 있음을 알아야합니다 . 크롬에게만 알려진 이유 때문에 지난 4 년간 WHERE절 에서 배열 비교기를 사용할 수 없다고 생각했습니다 . 그 시절은 이제 사라졌습니다. (어렸을 때 머리에 떨어 졌으므로 아마도 나일뿐입니다).
GT.

1
@GT .: 그것의 요지 : 모든 boolean 표현은 WHERECrom 기꺼이 절 에서 작동합니다 .
Erwin Brandstetter

90

내가 잡은 함정을 조심하십시오 : 배열에 특정 값이 존재하지 않는지 확인할 때 다음을 수행해서는 안됩니다.

SELECT value_variable != ANY('{1,2,3}'::int[])

하지만 사용

SELECT value_variable != ALL('{1,2,3}'::int[])

대신에.


2
이중 부정의 종류; 자신의 사용주의 ALLANY
vol7ron

43
SELECT NOT value_variable = ANY('{1,2,3}'::int[])더 읽기
쉬울 것입니다

28

그러나 다른 방법이 있다면 공유하십시오.

두 배열을 비교할 수 있습니다. 왼쪽 배열의 값 중 하나가 오른쪽 배열의 값과 겹치면 true를 반환합니다. 일종의 해킹이지만 작동합니다.

SELECT '{1}'   && '{1,2,3}'::int[];  -- true
SELECT '{1,4}' && '{1,2,3}'::int[];  -- true
SELECT '{4}'   && '{1,2,3}'::int[];  -- false
  • 첫 번째 쿼리와 두 번째 쿼리에서 value 1는 올바른 배열에 있습니다.
  • true4이 올바른 배열에 포함되어 있지 않더라도 두 번째 쿼리는입니다 .
  • 세 번째 쿼리의 경우 왼쪽 배열 (즉, 4)의 값 이 오른쪽 배열에 없으므로 반환합니다.false

배열에 값을 갖기 위해 다른 테이블에서 열을 어떻게 검색 할 수 있습니까? 예를 들어, style_id가 들어간 맥주에서 select * (id가 1 인 사용자의 기본 설정 선택)가 1을 제한합니다. style_id는 정수 데이터 유형입니다. preferences is integer []이 오류가 발생합니다 오류 : operator 존재하지 않습니다 : integer = integer [] LINE 1 : style_id가있는 맥주에서 select * (select preferences f ... ^ HINT : 주어진 이름과 인수 유형과 일치하는 연산자가 없습니다. 명시 적 유형 캐스트를 추가해야 할 수도 있습니다
HP

@HP이 문제를 해결하는 방법은 여러 가지가 있습니다. 새로운 질문을해야합니다.
vol7ron

기존 질문이 없습니까? @ vol7ron
HP

@HP 전혀 아니지만, 의견은 질문이나 답변에 관한 의견을위한 것입니다. 일반적으로 더 많은 정보를 추가하거나 해결되지 않은 더 많은 정보를 요청합니다. 이 답변과 관련이없는 질문을하고 있습니다. 나는 당신이 질문이 아니라 새로운 글로 질문함으로써 더 많은 행운을 가질 것이라고 생각합니다.;)
vol7ron

@HP 질문을 게시하지 않았다면 여기에서 확인할 수 있습니다 : sqlfiddle.com/#!15/144cd/3 수행 할 작업의 예-배열을 풀어야하기 때문에 문제가 다릅니다.
vol7ron

4

unnest사용할 수 있습니다. 이 일련의 행으로 배열을 확장하고 단순히 값을 확인하여 존재 여부를 이용하여 간단 같다 INNOT IN.

예 :

  1. 아이디 => UUID

  2. exception_list_ids => uuid []

select * from table where id NOT IN (select unnest(exception_list_ids) from table2)


예. 내 쿼리 계획에서 SELECT UNNEST는 = ANY만큼 좋지 않습니다. 쿼리 계획을 확인하여 원하는 것을 기대하는지 확인하는 것이 좋습니다.
Rob Bygrave

3

배열에서 요소의 존재를 찾을 때 postgres의 SQL 파서를 전달하려면 적절한 캐스팅이 필요합니다. 다음은 join 절에서 array contains 연산자를 사용하는 쿼리 예입니다.

간단히하기 위해 관련 부분 만 나열합니다.

table1 other_name text[]; -- is an array of text

표시된 SQL의 결합 부분

from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]

다음은 또한 작동합니다

on t2.panel = ANY(t1.other_name)

구문 분석에서 열의 정확한 유형을 파악하기 위해 테이블 ​​정의를 가져올 필요가 없기 때문에 추가 캐스팅이 필요하다고 생각합니다. 다른 사람들은 이것에 의견을주십시오.


1

안녕 하나는 나를 위해 잘 작동, 아마도 누군가에게 유용

array_column :: text ilike ANY (ARRAY [ '% text_to_search %':: text]); your_table에서 *를 선택하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.