2012-06-27 3 views
97

Мне нужен способ проверить, существует ли значение в заданном массиве. До сих пор я придумал что-то вроде этогоПроверьте, существует ли значение в массиве Postgres

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

, но я продолжаю думать, должен быть более простой способ это, я просто не могу видеть это.

Edit: Просто понял, что я мог бы сделать это

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

Это намного лучше, и я полагаю, будет достаточно, но если у вас есть другие способы сделать это, пожалуйста, поделитесь.

ответ

174

Simpler с ANY construct:

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

Правый операнд ANY (в скобках) может быть либо set (result of a subquery, for instance)илиarray. Есть несколько способов, чтобы использовать его:

Важно разница: Array operators (<@, @> et al.) ожидать массива типов в качестве операндов и support GIN or GiST indices в стандартном распределении PostgreSQL, в то время как ANY конструкция ожидает элемент типа в качестве левого операнда и не поддерживает эти индексы. Пример:

Все это не работает для NULL элементов. Для проверки NULL:

+0

Спасибо. Должен был пропустить эту часть руководства. Это отлично работает. Он имеет побочный эффект автоматического литья. Пример: SELECT 1 :: smallint = ANY ('{1,2,3}' :: int []) работает. Просто не забудьте поставить ANY() в правой части выражения. –

+0

Спасибо за ответ. Возникла проблема, когда мой запрос работал на локальном, но в героике было метать это сообщение: «ANY/ALL (array) требует массив на правой стороне», добавление ':: int []' делало обаяние. – kinduff

+0

где S.employee_id <@ ANY ('"+ employeeIDsArray +"' :: int []) Это возвращает значение PSQLException: ERROR: отсутствует значение измерения – Ramprasad

42

Берегитесь ловушку меня в: При проверке, если определенное значение не присутствует в массиве, вы не должны делать:

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

но использовать

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

вместо этого.

+1

Вид двойной отрицательный; обратите внимание на его использование 'ALL' vs' ANY' – vol7ron

+15

'SELECT NOT value_variable = ANY ('{1,2,3}' :: int [])' может быть более читаемым –

12

but if you have other ways to do it please share.

Вы можете сравнить два массива. Если какое-либо из значений в левом массиве перекрывает значения в правильном массиве, оно возвращает true. Это хаки, но это работает.

SELECT '{1}' && '{1,2,3}'::int[]; -- true 
SELECT '{1,4}' && '{1,2,3}'::int[]; -- true 
SELECT '{4}' && '{1,2,3}'::int[]; -- false 
  • В первом и втором запросе, значение 1 находится в правильном массиве
  • Обратите внимание, что второй запрос true, даже если значение 4 не содержится в правильном массиве
  • Для третий запрос, никакие значения в левом массиве (т. е. 4) не находятся в правильном массиве, поэтому он возвращает false
+0

как я могу найти столбец из другой таблицы иметь значение в массиве? , например. выберите * из пива, где style_id in (выберите предпочтения от пользователей, где id = 1) limit 1; style_id - целочисленный тип данных; preferences is integer [] Я получаю эту ошибку ОШИБКА: оператор не существует: integer = integer [] LINE 1: выберите * из пива, где style_id in (выберите предпочтения f ...^СОВЕТ: оператор не соответствует указанному имя и тип аргумента. Возможно, вам нужно будет добавить явные типы приведения. –

+0

@HP Существуют различные способы решения этого вопроса, вы должны задать новый вопрос – vol7ron

+0

, вы уверены, что не существует вопроса? @ vol7ron –

0

unnest также может быть использован. Он расширяет массив до набора строк, а затем просто проверяет наличие или нет, так же просто, как с использованием IN или NOT IN.

например.

  1. ID => UUID

  2. exception_list_ids => UUID []

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

+0

Да. Обратите внимание, что в моих планах запросов SELECT UNNEST не так хорош, как = ЛЮБОЙ. Я бы рекомендовал проверить планы запросов, чтобы узнать, получаете ли вы то, что хотите/ожидаете. –

0

При поиске существования элемента в массиве, для прохождения анализатора SQL postgres требуется правильное кастинг. Вот один пример запроса с использованием массива содержит оператор в присоединиться к статье:

Для простоты я только перечислить соответствующую часть:

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) 

Я просто догадываюсь, что дополнительное литье является обязательным красным, потому что синтаксический анализ не должен отображать определение таблицы для определения точного типа столбца. Другие, пожалуйста, прокомментируйте это.